Вместо функции Int используйте функцию cLng . В то время как Int
будет отсекать десятичные дроби, cLng
округляется до Long
.
Пример Int
обрезает
Int(99.2) '= 99
Int(99.5) '= 99
Int(99.8) '= 99
, но cLng
будет округлять
cLng(99.2) '= 99
cLng(99.5) '= 100
cLng(99.8) '= 100
, поскольку компьютеры и калькуляторы вычисляют цифры c, а не алгебры c вероятно, существует проблема точности в вычислениях, и Log(1000) / Log(10)
это не точно алгебра c 3
, а цифра c 3
, что-то вроде 2.99999999999998
, что Int
обрезается до 2
, но cLng
округляется до 3
.
Обратите внимание, что Excel - это программа для вычисления чисел c, а значения типа Double
не являются точными значениями. Десятичные дроби (как и для любого стандартного калькулятора тоже) рассчитываются только с определенной точностью. Так что Double
type 3
- это не 3
, а что-то очень похожее на 3
, например 2.99999999999998
. Таким образом, функция Log возвращает Double
, а также деление Log(1000) / Log(10)
возвращает Double
, и это не точно 3
, но очень близко к 3
.
Обратите внимание, что это не ошибка, а характер числовых c вычислений, которые никогда не являются точными, а только точными, в то время как алгебраические c вычисления могут быть точными.
та же проблема возникает при сравнении значений типа Double
:
If DoubleA = DoubleB Then 'might not work
Здесь необходимо использовать что-то вроде
If (DoubleA - DoubleB) ^ 2 < (10^ - Digits)^2
, где Digits
- это количество цифр, которое необходимо то же. Пример
DoubleA = 0.9999999999
DoubleB = 1.0000000001
, тогда Digits
должно быть <= 9
, чтобы считать их равными.
Если вам нужно делать это часто, то для этого будет удобно использовать функцию:
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
и назовите его как
Debug.Print IsDoubleValueTheSame(0.9999999999, 1.0000000001, 9) 'true
Debug.Print IsDoubleValueTheSame(0.9999999999, 1.0000000001, 10) 'false
Итак, вернемся к исходному примеру:
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)
на самом деле 3
с точностью до 15
цифр и 16ᵗʰ di git отличается.
Дополнительная информация об этом: