mat*_*guy 2 python floating-point precision numpy
请原谅我提出这样一个愚蠢的问题,但我在网上找不到任何答案。
Numpy的dtype文档仅显示每种浮点类型的X位指数和Y位尾数,但我无法将X位指数和Y位尾数转换为小数点之前/之后的多少位数。有没有简单的公式/表格可以查询?
先感谢您
SRE*_*DAN 13
为了保持简单。
通常随着数值大小的增大或减小,精度的小数位数分别增大或减小
一般来说,
Data-Type | Precision
----------------------
float16 | 3 to 4
float32 | 6 to 9
float64 | 15 to 17
float128 | 18 to 34
Run Code Online (Sandbox Code Playgroud)
如果你明白的话别忘了给答案点赞
按位属性:
float16:1 个符号位、5 个指数位、10 位有效数(小数部分)。
float32:1 个符号位、8 个指数位和 23 位有效数(小数部分)。
float64:1 个符号位、11 个指数位和 52 个小数位。
float128:1 个符号位、15 个指数位和 112 个小数位。
这并不像通常预期的那么简单。为了保证尾数的准确性,通常有两个值:
给定以十进制表示的值,如果从十进制转换为选定的二进制格式并返回(使用默认舍入),则可以保证保留多少个十进制数字。
给定二进制格式的值,如果将值转换为十进制格式并返回原始二进制格式(再次使用默认舍入),则需要多少个十进制数字以保持原始值不变。
在这两种情况下,十进制表示形式均视为与所用指数无关,没有前导和尾随零(例如,所有0.0123e4、1.23e2、1.2300e2、123、123.0、123000.000e-3均为3位数字)。
对于32位二进制浮点数,这两个大小分别为6和9个十进制数字。在C <float.h>中,它们是FLT_DIG和FLT_DECIMAL_DIG。(这很奇怪,32位浮点数保留了所有数字总数的7位十进制数字,但是有例外。)在C ++中,查看std :: numeric_limits <float> :: digits10和std :: numeric_limits <float>: :max_digits10。
对于64位二进制浮点数,分别为15和17(分别为DBL_DIG和DBL_DECIMAL_DIG;以及std :: numeric_limits <double> :: {digits10,max_digits10})。
它们的通用公式(thx2 @MarkDickinson)
floor((p-1)*log10(2))ceil(1+p*log10(2))其中p,尾数是位数(对于标准化的IEEE754情况,其中包括一个隐藏的数)。
另外,在C ++ 数值限制页面上有一些数学解释的注释:
标准的32位IEEE 754浮点类型具有24位小数部分(写入了23位,暗含一个),这可能表明它可以表示7位小数(24 * std :: log10(2)为7.22),但是相对舍入误差是不一致的,并且某些具有7个十进制数字的浮点值无法转换为32位浮点数和返回值:最小的正例为8.589973e9,在往返之后变为8.589974e9。这些舍入误差不能超过表示中的一位,并且digit10的计算公式为(24-1)* std :: log10(2),为6.92。四舍五入得出值6。
在注释中查找16位浮点数和128位浮点数的值(但请参见下文,了解实际的128位浮点数)。
对于指数而言,这是更简单的,因为每个边界值(最小归一化,最小非归一化,最大代表)都是准确的,并且可以轻松获得和打印。
@PaulPanzer建议使用numpy.finfo。它首先给出这些值({format} _DIG); 也许是您搜索的东西:
>>> numpy.finfo(numpy.float16).precision
3
>>> numpy.finfo(numpy.float32).precision
6
>>> numpy.finfo(numpy.float64).precision
15
>>> numpy.finfo(numpy.float128).precision
18
Run Code Online (Sandbox Code Playgroud)
但是,在大多数系统上(我的系统是x86-84上的Ubuntu 18.04),float128的值令人困惑。它确实适用于具有64位有效位数的80位x86“扩展”浮点型;实际的IEEE754 float128具有112个有效位,因此实际值应为33,但numpy以此名称表示另一种类型。有关详细信息,请参见此处:通常,float128是numpy中的错觉。
UPD3:您提到过-IEEE754集中float8没有这种类型。可以想象这种类型用于完全特定的目的,但是对于任何通用用法,它的范围都太窄了。