float неточны
Я не покупаю этот аргумент, потому что точная мощность двух представлена точно на большинстве платформ (с базовой плавающей точкой IEEE 754).
Итак, если мы действительно хотим, чтобы log2 с точной степенью 2 был точным, мы можем.
Я продемонстрирую это в Squeak Smalltalk, потому что в этом языке легко изменить базовую систему, но язык не имеет особого значения, вычисления с плавающей запятой универсальны, а объектная модель Python не так уж далека от Smalltalk.
Для ведения журнала в базе n существует функция log:, определенная в Number, которая наивно использует неперианский логарифм ln
:
log: aNumber
"Answer the log base aNumber of the receiver."
^self ln / aNumber ln
self ln
(возьмите неперианский логарифм получателя), aNumber ln
и /
- это три операции, которые будут округлять результат до ближайшего числа с плавающей точкой, и эти ошибки округления могут накапливаться ... Так что наивная реализация зависит от наблюдаемая вами ошибка округления, и я предполагаю, что реализация функции журнала в Python не сильно отличается.
((2 raisedTo: 31) log: 2) = 31.000000000000004
Но если я изменю определение следующим образом:
log: aNumber
"Answer the log base aNumber of the receiver."
aNumber = 2 ifTrue: [^self log2].
^self ln / aNumber ln
предоставить общий log2 в классе Number:
log2
"Answer the base-2 log of the receiver."
^self asFloat log2
и это уточнение в классе Float:
log2
"Answer the base 2 logarithm of the receiver.
Care to answer exact result for exact power of two."
^self significand ln / Ln2 + self exponent asFloat
, где Ln2
- это константа (2 ln), тогда я получаю точный log2 для точной степени двух, потому что значимое такого числа = 1,0 (включая субнормальное для показателя пика / значимости и определения) и 1.0 ln = 0.0
.
Реализация довольно тривиальна и должна без труда переводиться в Python (возможно, в VM); стоимость времени выполнения очень дешевая, поэтому важно только то, насколько важной мы считаем эту функцию или нет.
Как я всегда говорю, тот факт, что результаты операций с плавающей запятой округляются до ближайшего (или любого другого направления округления) представляемого значения, не является лицензией на трату ulp. Точность сопряжена с затратами, как с точки зрения штрафа за время выполнения, так и с точки зрения сложности реализации, поэтому она требует компромиссов.