Который более точен, x **.5 или math.sqrt (x)?

Вы можете получить хеш-ключ Facebook, используя отпечаток вашей системы SHA1. Иногда нам нужно использовать 2 хэш-ключа для Android. Один для устройства, на котором нет приложения Facebook (это вы можете получить с помощью SHA1), а второй - для устройств, на которых установлено приложение Facebook. Для этого вам необходимо ввести ключ, отображаемый на устройстве во время ошибки входа в Facebook в приложении.

22
задан Gabe 23 September 2013 в 18:06
поделиться

8 ответов

Ни один из них не является более точным, оба они расходятся от фактического ответа в равных частях:

>>> (8885558**0.5)**2
8885557.9999999981
>>> sqrt(8885558)**2
8885558.0000000019

>>> 2**1023.99999999999
1.7976931348498497e+308

>>> (sqrt(2**1023.99999999999))**2
1.7976931348498495e+308
>>> ((2**1023.99999999999)**0.5)**2
1.7976931348498499e+308

>>> ((2**1023.99999999999)**0.5)**2 - 2**1023.99999999999
1.9958403095347198e+292
>>> (sqrt(2**1023.99999999999))**2 - 2**1023.99999999999
-1.9958403095347198e+292

http://mail.python.org/pipermail/python-list/2003-November/ 238546.html

Математический модуль является оболочкой платформы C библиотечные математические функции того же имена; math.pow () наиболее полезен, если тебе нужно (или просто хочется) кайф совместимость с расширениями C вызов C pow () .

__ builtin __. pow () - это реализация инфикса Python ** оператор и занимается сложными числа, неограниченные целочисленные степени и также модульное возведение в степень (C pow () не обрабатывает ни одно из них).

** является более полным. math.sqrt , вероятно, просто реализация sqrt на языке C, которая, вероятно, связана с pow .

25
ответ дан 29 November 2019 в 04:02
поделиться

Both the pow function and the math.sqrt() function can calculate results that are more accurate than what the default float type can store. I think the errors you're seeing is a result of the limitations of floating point math rather than inaccuracies of the functions. Also, since when is a difference of ~10^(-13) a problem when taking the square root of a 7 digit number? Even the most accurate physics calculations seldom requires that many significant digits...

Another reason to use math.sqrt() is that it's easier to read and understand, which generally is a good reason to do things a certain way.

11
ответ дан 29 November 2019 в 04:02
поделиться

Теоретически math.sqrt должен иметь более высокую точность, чем math.pow. См. Метод Ньютона для вычисления квадратных корней [0]. Однако ограничение числа десятичных цифр для числа с плавающей запятой в python (или двойного числа C), вероятно, замаскирует разницу.

[0] http://en.wikipedia.org/wiki/Integer_square_root

1
ответ дан 29 November 2019 в 04:02
поделиться

Используйте десятичное , чтобы найти более точные квадратные корни:

>>> import decimal
>>> decimal.getcontext().prec = 60
>>> decimal.Decimal(8885558).sqrt()
Decimal("2980.86531061032678789963529280900544861029083861907705317042")
7
ответ дан 29 November 2019 в 04:02
поделиться

Каждый раз, когда вам предоставляется выбор между двумя встроенными в язык функциями, более конкретная функция почти всегда будет равна или лучше общей (поскольку если бы она была хуже, кодировщики просто реализовали бы это в терминах общей функции). Sqrt более конкретен, чем универсальное возведение в степень, поэтому вы можете ожидать, что это лучший выбор. И это так, по крайней мере, с точки зрения скорости. С точки зрения точности, вы не имеете дело с достаточной точностью ваших чисел, чтобы можно было сказать.

Примечание. Чтобы уточнить, sqrt быстрее в Python 3.0. В старых версиях Python он работает медленнее. См. Измерения Дж. Ф. Себастьяна на Что быстрее в Python: x **. 5 или math.sqrt (x)? .

4
ответ дан 29 November 2019 в 04:02
поделиться

У меня другое поведение. Возможно, ошибка специфична для платформы? На amd64 я получаю следующее:

Python 2.5.2 (r252:60911, Mar 10 2008, 15:14:55) 
[GCC 3.3.5 (propolice)] on openbsd4
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> math.sqrt(8885558) - (8885558**.5)
0.0
>>> (8885558**.5) - math.sqrt(8885558)
0.0
1
ответ дан 29 November 2019 в 04:02
поделиться

Это должно быть специфично для платформы, потому что я получаю разные результаты :

Python 2.5.1 (r251:54863, Jan 13 2009, 10:26:13) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
>>> 8885558**.5 - math.sqrt(8885558)
0.0

Какую версию Python вы используете и какую ОС?

Я предполагаю, что это как-то связано с продвижением и кастингом. Другими словами, поскольку вы выполняете 8885558 **. 5, 8885558 необходимо повысить до числа с плавающей запятой. Все это обрабатывается по-разному в зависимости от операционной системы, процессора и версии Python. Добро пожаловать в чудесный мир арифметики с плавающей запятой. : -)

3
ответ дан 29 November 2019 в 04:02
поделиться

У меня такая же проблема с вами в Win XP Python 2.5.1, а у меня нет в 32-битном Gentoo Python 2.5.4. Это вопрос реализации библиотеки C.

Теперь в Win math.sqrt (8885558) ** 2 дает 8885558.0000000019 , а (8885558 **. 5 ) ** 2 дает 8885557.9999999981 , что, похоже, равносильно тому же эпсилону.

Я говорю, что на самом деле нельзя сказать, какой из них «лучше».

3
ответ дан 29 November 2019 в 04:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: