Функция входа в Excel (VBA) - не дает мне правильный ответ - PullRequest
1 голос
/ 05 апреля 2020

В этом фрагменте кода ниже значение temp_int2 равно 1, для меня нет смысла. -> log (1000) = 3, то есть журнал базы 10, функция журнала - база 'e'.

Я не уверен, что это функция "INT", которая проблематична c, но может кто-то Пожалуйста, помогите.

enter image description here

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))

1 Ответ

2 голосов
/ 06 апреля 2020

Вместо функции 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 отличается.

Дополнительная информация об этом:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...