Форум сайта python.su
Пишу сейчас для работы скрипт на питоне, который должен обрабатывать данные. И наткнулся на такой глюк.
Есть кусок кода:
# -*- coding: utf-8 -*-
import cmath
import numpy
import math
count = 64
dt = 25.0e-12
df = 1.0 / (count * dt)
r = 0.85
c = 3.0e8
i = complex (0.0, 1.0)
e =
e_abs =
print e_abs
Смотрим на результат и медленно офигеваем:
[1.0, 1.0, 1.0, 1.0, 0.99999999999999989, 1.0000000000000002, 1.0, 1.0, 1.0, 1.0, 1.4161689365379793e+019, 1.5577858301917772e+019, 1.6994027238455753e+019, 1.8410196174993732e+019, 1.9826365111531713e+019, 2.1242534048069689e+019, 2.265870298460767e+019, 2.4074871921145647e+019, 2.5491040857683628e+019, 2.6907209794221605e+019, 2.8323378730759586e+019, 2.9739547667297563e+019, 3.1155716603835544e+019, 3.257188554037352e+019, 3.3988054476911505e+019, 3.5404223413449486e+019, 3.6820392349987463e+019, 3.8236561286525444e+019, 3.9652730223063425e+019, 4.1068899159601398e+019, 4.2485068096139379e+019, 4.390123703267736e+019, 4.5317405969215341e+019, 4.6733574905753313e+019, 4.8149743842291294e+019, 4.9565912778829275e+019, 5.0982081715367256e+019, 5.2398250651905229e+019, 5.381441958844321e+019, 5.5230588524981191e+019, 5.6646757461519172e+019, 5.8062926398057144e+019, 5.9479095334595125e+019, 6.0895264271133106e+019, 6.2311433207671087e+019, 6.372760214420906e+019, 6.5143771080747041e+019, 6.6559940017285022e+019, 6.7976108953823011e+019, 6.9392277890360992e+019, 7.0808446826898973e+019, 7.2224615763436945e+019, 7.3640784699974926e+019, 7.5056953636512907e+019, 7.6473122573050888e+019, 7.7889291509588869e+019, 7.930546044612685e+019, 8.0721629382664815e+019, 8.2137798319202796e+019, 8.3553967255740776e+019, 8.4970136192278757e+019, 8.6386305128816738e+019, 8.7802474065354719e+019, 8.92186430018927e+019]
Модуль чисто мнимого числа скачком становится вместо 1.0 каким-то здоровенным числом, которое еще линейно растет:
Теперь заменяем модуль cmath на numpy:
# -*- coding: utf-8 -*-
import cmath
import numpy
import math
count = 64
dt = 25.0e-12
df = 1.0 / (count * dt)
r = 0.85
c = 3.0e8
i = complex (0.0, 1.0)
e =
e_abs =
И получаем вполне нормальный результат.
PS. Все это проверял на Python 2.5, WinXP + SP2.
PPS. А как на этом форуме можно раскрасить питоновский код?
Отредактировано (Окт. 10, 2007 08:56:35)
Офлайн
раскрасить: code:python
Офлайн
Спасибо, раскрасил.
Офлайн
в багтрекере питона не искали упоминание про такой глюк? может он уже известен?
Офлайн
Нет, еще не смотрел. Сегодня вечером поищу. Заодно можно попробовать питон 2.5.1 поставить.
Офлайн
В питоне 2.5.1 ничего не изменилось, и в багтрекере такого бага не нашел. В
Офлайн
а вы смотрели сами комплексные числа, их значения?
Офлайн
около 9.3e18 достигается предел точности типа float64:
>>> x1=9.2e18j
>>> x2=9.3e18j
>>> cmath.exp(x1)
(0.8892436064235012+0.45743393887524936j)
>>> cmath.exp(x2)
(9.3e+018+9.3e+018j)
Если посчитать двоичный логарифм от 9.3e18, видно, что используются все 63 разряда плюс 1 на знак:
>>> math.log(9.3e18)/math.log(2)
63.011936424193195
Так что это не глюк, а достижение предела точности. Дальше идет линейная зависимость, т.к. значимым оказывается только первый член ряда Тэйлора при вычислении функции. Видимо, модуль numpy либо использует большую разрядность, либо перед применением numpy.exp делает проверку на x.real==0.
А зачем Вам нужны такие огромные числа?
Отредактировано (Окт. 11, 2007 06:56:00)
Офлайн
Сами числа еще не смотрел, пока руки не дошли. Надо будет действительно глянуть что там возвращает numpy. А вообще это для обработки сигналов. Там в формуле частота большая (гигагерцы), да еще и на скорость света умножается.
Офлайн
согласен про точность. именно это и пришло в голову когда начал смотреть на величину экспоненты.
Jenyay: у вас при вычислении экспоненты там куча констант. Попробуйте их немного переработать, чтобы уменьшить порядок чисел. Все равно на таких частотах единицы Герц никому не интересны.
Офлайн