Longdouble(1e3000) става инфо: Какво мога да направя?

(Повечето други свързани въпроси в мрежата се отнасят до преобразуване между longdouble на C и python. Този въпрос е различен.)

Не виждам защо не мога правилно да получа longdouble в python по този начин:

In [72]: import numpy as np

In [73]: np.longdouble(1e3000)
Out[73]: inf

Изглежда, че трябва да уведомя моята Python конзола, че 1e3000 е longdouble вместо double. Как мога да направя това


person zell    schedule 24.05.2015    source източник
comment
Бих очаквал np.longdouble("1e3000") да работи, но получавам inf и там.   -  person Bill Lynch    schedule 24.05.2015
comment
И аз, същия резултат.   -  person zell    schedule 24.05.2015


Отговори (2)


Проблемът е, че като използва израз като ...(1e3000), анализаторът на Python трябва първо да изчисли какво е в скобите и да предаде резултата на извикването на функцията. Long double не е естествен тип, следователно стойността в скобите е inf - която се предава на конструктора longdouble. Фактът, че версията на низа е неуспешна, може би може да се счита за грешка в NumPy - това показва, че низът е преобразуван в Python float (което е "float64" или "double" в C) вътрешно, вероятно с помощта на нормалния конструктор на Python float.

Заобиколното решение е първо да се изгради дългият двоен обект със стойност, която е съвместима с Python float, и те да го умножат, за да достигнат до желаната стойност. Ако трябва да направите това с няколко стойности, използвайте масив NumPy вместо една стойност:

>>> x = np.longdouble(10)
>>> x
10.0
>>> x **= 3000
>>> x
9.9999999999999999999e+2999
person jsbueno    schedule 24.05.2015

Python няма "дълги двойни". Използвайки научна нотация, вие създавате плаващ литерал. Те не могат да представляват 1e3000, така че получавате инф. Ако използвате цели числа, може да успеете да направите това, от което се нуждаете: 10**3000.

person Ned Batchelder    schedule 24.05.2015
comment
Благодаря, но мисля, че този отговор е (частично) грешен. Моля, опитайте това в конзолата: np.longdouble(10**700) ==› OverflowError: long int е твърде голям за преобразуване в float - person zell; 24.05.2015
comment
@Gio: На моята платформа numpy.finfo(numpy.longdouble) претендира за максимална поддържана стойност от 1.18973149536e+4932 и аз също виждам inf. - person Bill Lynch; 24.05.2015
comment
@Gio Двойното не разделя дробната и целочислената част - то разделя дробната част от експонентата. Двойникът има формата 1.M * 2^E, където M и E (в допълнение към знаковия бит) се съхраняват в двойника. Това означава, че нямате нужда от 2326 бита, за да съхраните (приблизително) 10**700, просто имате нужда от достатъчно битове в експонентната част, за да съхраните числото 2325. - person sepp2k; 24.05.2015