Поскольку логарифм основания 10 для 1000 равен 3, можно ожидать, что Math::log(1000, 10)
вернет 3
. Вместо этого он возвращает 2.9999999999999996
.
Это связано с тем, что числа с плавающей точкой в Ruby не являются точными числами, как обсуждалось, например, здесь :
Число с плавающей запятой не является точным представлением чисел, как указано в ruby
документы
Объекты с плавающей точкой представляют неточные действительные числа, используя представление с плавающей точкой двойной точности в собственной архитектуре.
Это не ошибка ruby, поскольку поплавки могут быть представлены только фиксированным
количество байтов и поэтому не может правильно хранить десятичные числа.
В качестве альтернативы вы можете использовать ruby Rational или BigDecimal
К сожалению, при вызове Math::log(BigDecimal('1000'), BigDecimal('10'))
результат точно такой же. То же самое касается Math::log(Rational('1000'), Rational('10'))
. Существует также BigMath::log
, который делает что-то совершенно другое .
Теперь главный вопрос: как мы можем вычислить логарифм 10 для основания 10, чтобы получить точный результат: 3
?