In this code snippet below, the value of temp_int2 is 1, makes no sense to me. –> log(1000) = 3, that is log of base 10, the log function is base ‘e’.
im not sure if its the “INT” function which problematic but could someone please assist.
temp_int2 = Int(Log(1000) / Log(10)) - 1 'temp_int2 = Int(Log(cap_dec) / Log(10)) - 1 MsgBox ("Value of log functuon -->" & CStr(Log(cap_dec) / Log(10)) & " value after log function " & CStr(temp_int2))
Int will cut off
Int(99.2) '= 99 Int(99.5) '= 99 Int(99.8) '= 99
cLng will round
cLng(99.2) '= 99 cLng(99.5) '= 100 cLng(99.8) '= 100
since computers and calculators calculate numeric and not algebraic there is probably a precision issue in calculation and
Log(1000) / Log(10) is not exactly an algebraic
3 but a numeric
3 that is something like
Int will cut off to
cLng will round to
Note that Excel is a numeric calculation program and values of type
Double are not exact values. The decimals are (as with any standard calculator too) only calculated up to a defined precision.
3 is not a
3 but something very close to
2.99999999999998. So the Log function returns a
Double and also a devision
Log(1000) / Log(10) returns a
Double and this is not exactly
3 but very close to
Note that this is not a bug but in the nature of numeric calculations which are never exact but only precise, while algebraic calculations can be exact.
The same problem occurs when comparing values of type
If DoubleA = DoubleB Then 'might not work
Here you need to use something like
If (DoubleA - DoubleB) ^ 2 < (10^ - Digits)^2
Digits is the number of digits that need to be the same. Example
DoubleA = 0.9999999999 DoubleB = 1.0000000001
Digits needs to be
<= 9 to consider them as equal.
If you need to do that often then it comes handy to use a function for that:
Option Explicit Public Function IsDoubleValueTheSame(DoubleA As Double, DoubleB As Double, Optional Digits As Long = 12) As Boolean IsDoubleValueTheSame = (DoubleA - DoubleB) ^ 2 < (10 ^ -Digits) ^ 2 End Function
and call it like
Debug.Print IsDoubleValueTheSame(0.9999999999, 1.0000000001, 9) 'true Debug.Print IsDoubleValueTheSame(0.9999999999, 1.0000000001, 10) 'false
So to come back to your initial example:
Debug.Print Log(1000) / Log(10) = 3 'false Debug.Print IsDoubleValueTheSame(Log(1000) / Log(10), 3, 15) 'true Debug.Print IsDoubleValueTheSame(Log(1000) / Log(10), 3, 16) 'false
Log(1000) / Log(10) is actually
3 precise up to
15 digits and the 16ᵗʰ digit is different.
Further information about this:
- Numeric precision in Microsoft_Excel (Wikipedia)
- Floating-point arithmetic may give inaccurate results in Excel (Microsoft documentation)
- Compare double in VBA precision problem (Stack Overflow)