TG Telegram Group & Channel
Питонические атаки | United States America (US)
Create: Update:

Ещё один прикол в 3.12 — встроенная функция sum() теперь использует специальный алгоритм для сложения чисел с плавающей точкой с минимальной потерей точности (прочитать про алгоритм можно на вики).

Раньше было как, складываешь 10 чиселок, где в результате ожидаешь получить 1, но получаешь что-то немного другое:

>>> sum([0.1] * 10)
0.9999999999999999

И ладно бы оно просто всегда ошибалось одинаково, дак ведь погрешность ещё и зависит от порядка, в котором складывать числа:

>>> sum([0.1] * 5 + [0.05] * 10)
1.0000000000000004
>>> sum([0.05] * 10 + [0.1] * 5)
0.9999999999999999
>>> sum([0.1, 0.05, 0.05, 0.05, 0.05, 0.1, 0.1, 0.05, 0.05, 0.1, 0.05, 0.05, 0.05, 0.1, 0.05])
1.0000000000000002

А вы разве не знали, что сложение float'ов не коммутативно?

Но была специальная функция math.fsum(), которая всё делает правильно:

>>> math.fsum([0.1] * 10)
1.0
>>> math.fsum([0.1] * 5 + [0.05] * 10)
1.0
>>> math.fsum([0.05] * 10 + [0.1] * 5)
1.0

Дак вот в 3.12 встроенная функция sum() даёт такие же результаты, как math.fsum(). По крайней мере, я не смог найти примера, где они дали бы разный результат. Кроме того, по моим замерам, sum() работает ещё и раза в полтора быстрее math.fsum():

>>> timeit.timeit("sum([0.05] * 10 + [0.1] * 5)")
0.26875441599986516
>>> timeit.timeit("math.fsum([0.05] * 10 + [0.1] * 5)", setup="import math")
0.34194887499961624

Кто-нибудь понимает, зачем теперь нужна math.fsum()?

Ещё один прикол в 3.12 — встроенная функция sum() теперь использует специальный алгоритм для сложения чисел с плавающей точкой с минимальной потерей точности (прочитать про алгоритм можно на вики).

Раньше было как, складываешь 10 чиселок, где в результате ожидаешь получить 1, но получаешь что-то немного другое:

>>> sum([0.1] * 10)
0.9999999999999999

И ладно бы оно просто всегда ошибалось одинаково, дак ведь погрешность ещё и зависит от порядка, в котором складывать числа:

>>> sum([0.1] * 5 + [0.05] * 10)
1.0000000000000004
>>> sum([0.05] * 10 + [0.1] * 5)
0.9999999999999999
>>> sum([0.1, 0.05, 0.05, 0.05, 0.05, 0.1, 0.1, 0.05, 0.05, 0.1, 0.05, 0.05, 0.05, 0.1, 0.05])
1.0000000000000002

А вы разве не знали, что сложение float'ов не коммутативно?

Но была специальная функция math.fsum(), которая всё делает правильно:

>>> math.fsum([0.1] * 10)
1.0
>>> math.fsum([0.1] * 5 + [0.05] * 10)
1.0
>>> math.fsum([0.05] * 10 + [0.1] * 5)
1.0

Дак вот в 3.12 встроенная функция sum() даёт такие же результаты, как math.fsum(). По крайней мере, я не смог найти примера, где они дали бы разный результат. Кроме того, по моим замерам, sum() работает ещё и раза в полтора быстрее math.fsum():

>>> timeit.timeit("sum([0.05] * 10 + [0.1] * 5)")
0.26875441599986516
>>> timeit.timeit("math.fsum([0.05] * 10 + [0.1] * 5)", setup="import math")
0.34194887499961624

Кто-нибудь понимает, зачем теперь нужна math.fsum()?


>>Click here to continue<<

Питонические атаки






Share with your best friend
VIEW MORE

United States America Popular Telegram Group (US)