Существует официальная рекомендация для версий PHP, которые не поддерживают array_colum()
в разделе «см. Также»:
»Рекомендуемая реализация пользовательского пространства для PHP ниже, чем 5,5
Их рекомендация является еще одним подходом if (!function_exists('array_column'))
, но код фактически извлечен из библиотеки array_column и немного более обобщен, чем примеры на этой странице.
Этого следовало ожидать от компьютерной арифметики. Он подчиняется определенным правилам, таким как IEEE 754 , которые, вероятно, не соответствуют математике, которую вы изучали в школе.
Если это на самом деле имеет значение, используйте десятичную дробь Python введите .
Пример:
from decimal import Decimal, Context
ctx = Context(prec=20)
two = Decimal(2)
ctx.divide(ctx.power(two, Decimal(31)).ln(ctx), two.ln(ctx))
Всегда предполагают, что операции с плавающей запятой будут содержать некоторую ошибку, и проверяют равенство с учетом этой ошибки (либо процентное значение, например 0,00001% или фиксированное значение, например 0,00000000001). Эта неточность дана, поскольку не все десятичные числа могут быть представлены в двоичном формате с точностью до фиксированного числа битов.
Ваш конкретный случай не входит в их число, если Python использует IEEE754, поскольку 31 должно быть легко представимо даже с одинарной точностью. Это'
Вы должны прочитать «Что должен знать каждый компьютерный ученый об арифметике с плавающей точкой».
Операции с плавающей запятой никогда не бывают точными. Они возвращают результат, который имеет приемлемую относительную ошибку для языковой / аппаратной инфраструктуры.
В общем, совершенно неверно предполагать, что операции с плавающей запятой точны, особенно с одинарной точностью. Раздел «Проблемы точности» из статьи Википедии о плавающих точках:)
Представление repr
( float .__ repr __
) числа в Python пытается вернуть строку цифр, максимально приближенную к реальному значению. при обратном преобразовании, учитывая, что арифметика IEEE-754 является точной до предела. В любом случае, если вы print
ed результат, вы не заметите:
>>> from math import log
>>> log(2**31,2)
31.000000000000004
>>> print log(2**31,2)
31.0
print
преобразует свои аргументы в строки (в данном случае через float .__ str __
]), который устраняет неточность, отображая меньше цифр:
>>> log(1000000,2)
19.931568569324174
>>> print log(1000000,2)
19.9315685693
>>> 1.0/10
0.10000000000000001
>>> print 1.0/10
0.1
обычно бесполезный 'ответ очень полезен, на самом деле :)
Это нормально. Я ожидал бы, что log10 будет более точным, чем log (x, y), поскольку он точно знает основание логарифма, также может быть некоторая аппаратная поддержка для вычисления логарифмов по основанию 10.
Двойные числа с плавающей запятой IEEE имеют 52 бита точности . Поскольку 10 ^ 15 <2 ^ 52 <10 ^ 16, двойное число имеет от 15 до 16 значащих цифр. Результат 31,000000000000004 является правильным для 16 цифр, так что это вполне ожидаемо.