Ответ 1
pi
не является точно представимым как плавающий Python (такой же, как тип платформы C double
). Используется наиболее близкое представимое приближение.
Здесь точная аппроксимация в моем ящике (вероятно, такая же, как на вашем ящике):
>>> import math
>>> (math.pi / 2).as_integer_ratio()
(884279719003555, 562949953421312)
Чтобы найти касательную этого отношения, я сейчас переключится на wxMaxima:
(%i1) fpprec: 32;
(%o1) 32
(%i2) tan(bfloat(884279719003555) / 562949953421312);
(%o2) 1.6331239353195369755967737041529b16
Таким образом, по сути, он идентичен тому, что вы получили. Используемое двоичное приближение к pi/2
немного меньше математического значения ( "бесконечная точность" ) pi/2
. Таким образом, вы получаете очень большую касательную вместо infinity
. Вычисленный tan()
подходит для фактического ввода!
По точно таким же причинам, например,
>>> math.sin(math.pi)
1.2246467991473532e-16
не возвращает 0. Аппроксимация math.pi
немного меньше, чем pi
, и отображаемый результат верен с учетом истины.
ДРУГИЕ СПОСОБЫ ВИДЕНИЯ math.pi
Существует несколько способов увидеть точное приближение:
>>> import math
>>> math.pi.as_integer_ratio()
(884279719003555, 281474976710656)
math.pi
точно соответствует математическому ( "бесконечной точности" ) значению этого отношения.
Или как точное поплавок в шестнадцатеричной нотации:
>>> math.pi.hex()
'0x1.921fb54442d18p+1'
Или в пути, наиболее легко понятном почти всем:
>>> import decimal
>>> decimal.Decimal(math.pi)
Decimal('3.141592653589793115997963468544185161590576171875')
В то время как это может быть не сразу очевидным, каждый конечный двоичный float точно представлен как конечный десятичный float (обратное неверно, например, десятичное 0.1
не является точно представимым как конечный двоичный float), а Decimal(some_float)
создает точный эквивалент.
Здесь истинное значение pi
, за которым следует точное десятичное значение math.pi
, а каретка на третьей строке указывает на первую цифру, в которой они отличаются:
true 3.14159265358979323846264338327950288419716939937510...
math.pi 3.141592653589793115997963468544185161590576171875
^
math.pi
теперь одно и то же для "почти всех", потому что почти все ящики теперь используют один и тот же двоичный формат с плавающей запятой (двойная точность IEEE 754). Вы можете использовать любой из приведенных выше способов, чтобы подтвердить, что на вашем поле, или найти точное приближение в использовании, если ваш ящик является исключением.