2012-01-30 4 views
19

Какая точность делает numpy.float128 для внутренней? Это __float128 или длинный двойной? (или что-то еще полностью !?)Какова внутренняя точность numpy.float128?

Потенциально следуйте на вопрос, если кто-нибудь знает: безопасно ли в C выпустить __float128 на (16-байтовый) длинный двойной, только с потерей точности? (это для взаимодействия с C lib, который работает с длинными удвоениями).

Редактировать: В ответ на комментарий платформа «Linux-3.0.0-14-generic-x86_64-with-Ubuntu-11.10-oneiric». Теперь, если numpy.float128 имеет различную точность, зависящую от платформы, это также полезно для меня!

Просто, чтобы быть ясным, это точность Меня интересует, а не размер элемента.

+0

«Версии с числом, соответствующим тому, что доступно на определенной платформе, которую вы используете, имеют по крайней мере несколько бит». 128 бит. Что сбивало с толку? Это специфичная платформа, и вы не указали платформу, что не позволяет ответить на ваш вопрос по вашему запросу. Пожалуйста ** уточните ** вопрос с точной информацией платформы Python. Подсказка: есть пакет 'platform'. –

+1

«кажется ясным» - предполагая, что он также говорит, что происходит, когда такого типа нет на конкретной платформе. –

+3

Я предполагаю, что точность numpy не зависит от платформы, поэтому информация обратная, безусловно, полезна. Я * предположил бы, что float128 отображает что-то наподобие __float128 внутренне, но длинная двойная тоже 128 бит в моей системе, так что это может быть разумно. –

ответ

7

Настоятельно рекомендуется использовать longdouble instead of float128, так как это довольно a mess, ATM. Python будет использовать его для float64 во время инициализации.

Внутри numpy это может быть двойной или длинный двойной. Он определен в npy_common.h и зависит от вашей платформы. Я не знаю, можете ли вы включить его из коробки в исходный код.

Если вам не нужна производительность в этой части вашего алгоритма, более безопасным способом было бы экспортировать его в строку и затем использовать strold.

+1

Правильно ли это в памяти, чтобы наложить указатель на массив float128 на длинный двойной? Он * * критичен по производительности;) –

+1

В дополнение к этому, читая npy_common.h, кажется, что он чувствителен к зависимой от платформы длине двойного (то есть использует длинный двойной, если длинный двойной - 128 бит), но мой умственный Препроцессор C немного ошибочен. –

+0

Хорошо, я в основном ответил на те вопросы, которые я думаю. Я * могу * отдать до длинного двойника, и все работает так, как ожидалось. Приведенные выше ссылки предполагают, что float128, если он существует, определяется как длинный двойной, но я не уверен в этом. –

32

numpy.longdouble относится к любому типу, который использует ваш компилятор C long double. В настоящее время это только расширенный тип с плавающей точкой с плавающей точкой, поддерживаемый numpy.

На x86-32 и x86-64 это 80-bit floating point type. На более экзотических системах это может быть что-то другое (IIRC на Sparc - это фактический 128-битный IEEE-флоат, а на PPC - double-double). (Это также может зависеть от того, какую ОС и компилятор вы используете - например, MSVC в Windows вообще не поддерживает какой-либо расширенной точности).

Numpy также экспортирует некоторое имя, например numpy.float96 или numpy.float128. Какое из этих имен экспортируется, зависит от вашей платформы/компилятора, но все, что вы получаете, всегда относится к тому же базовому типу, что и longdouble. Кроме того, эти имена очень вводят в заблуждение. Они не указывают 96- или 128-битный формат IEEE с плавающей запятой. Вместо этого они указывают количество бит выравнивания, используемое базовым типом long double. Так, например, на x86-32, long double - 80 бит, но получает до 96 бит для поддержки 32-битного выравнивания, а numpy вызывает это float96. На x86-64 long double снова является идентичным 80-битным типом, но теперь он заполняется до 128 бит для поддержки 64-битного выравнивания, а numpy вызывает это float128. Нет лишней точности, просто дополнительное дополнение.

Рекомендация: игнорировать имена float96/float128, просто используйте numpy.longdouble. Или еще лучше придерживаться двойников, если у вас нет поистине убедительной причины. Они будут более быстрыми, более переносимыми и т. Д.

Смежные вопросы