Reputation: 21
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))
Upvotes: 1
Views: 488
Reputation: 57693
Instead of the Int function use the cLng function. While Int
will cut off decimals, cLng
will round to a Long
.
Example Int
will cut off
Int(99.2) '= 99
Int(99.5) '= 99
Int(99.8) '= 99
but 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 2.99999999999998
which Int
will cut off to 2
but cLng
will round to 3
.
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.
So a Double
type 3
is not a 3
but something very close to 3
like 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 3
.
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 Double
:
If DoubleA = DoubleB Then 'might not work
Here you need to use something like
If (DoubleA - DoubleB) ^ 2 < (10^ - Digits)^2
where Digits
is the number of digits that need to be the same. Example
DoubleA = 0.9999999999
DoubleB = 1.0000000001
then 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
which means Log(1000) / Log(10)
is actually 3
precise up to 15
digits and the 16ᵗʰ digit is different.
Further information about this:
Upvotes: 2