Came across some code where the number of digits was being determined by casting the number to a string then using a len().
Function numOfDigits_len(n As Long) As Long
numOfDigits_len = Len(Str(n)) - 1
End Function
Now although this works I knew it would be slow compared to any method that didn't use strings, so I wrote one that uses log().
Function numOfDigits_log(n As Long) As Long
numOfDigits_log = Int(Log(n) / Log(10)) + 1
End Function
Cut run time by 1/2 which was great but there was something weird happening in a specific case.
n numOfDigits_log(n)
===== ====================
999 3
1000 3
1001 4
It would not handle 1000
properly. I figured it is because of floating point and rounding issues.
Function numOfDigits_loop(ByVal n As Long) As Long
Do Until n = 0
n = n \ 10
numOfDigits_loop = numOfDigits_loop + 1
Loop
End Function
Wrote this which turned out to be ~10% slower as numbers got larger than 10^6 and seems to become slowly larger as n gets bigger. Which is fine if I was being pragmatic but I would like to find something more ideal.
Now my question is, is there a way to use the log() method accurately. I could do something like
Function numOfDigits_log(n As Long) As Long
numOfDigits_log = Int(Log(n) / Log(10) + 0.000000001) + 1
End Function
But it seems very "hacky". Is there a nicer way that's faster or as fast as the log() method? Note: I realize this kind of optimization is pointless in a lot of cases but now that I've come across this I would like to "fix" it
I've answered this before, but I couldn't find it, so here's the basics:
int i = ... some number >= 0 ...
int n = 1;
if (i >= 100000000){i /= 100000000; n += 8;}
if (i >= 10000){i /= 10000; n += 4;}
if (i >= 100){i /= 100; n += 2;}
if (i >= 10){i /= 10; n += 1;}
That's in C, but you get the idea.
A while loop guarantees correctness, i.e. it doesn't use any floating point calculations
int numDigits = 0;
while(num != 0) {
num /= 10;
numDigits++;
}
You can also speed this up by using a larger divisor
int numDigits = 0;
if(num >= 100000 || num <= -100000) {
int prevNum;
while(num != 0) {
prevNum = num;
num /= 100000;
numDigits += 5;
}
num = prevNum;
numDigits -= 5;
}
while(num != 0) {
num /= 10;
numDigits++;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With