那么float8,float16,float32,float64和float128可以包含多少个数字?

时间:2019-06-09 13:15:23

标签: python numpy floating-point precision

原谅我问这样一个愚蠢的问题,但我找不到在线答案。

Numpy's dtype documentation仅显示每种浮点类型的X位指数和Y位尾数,但是我无法将X位指数和Y位尾数转换为小数点之前/之后的多少位数。有什么简单的公式/表格可以查找吗?

提前谢谢

1 个答案:

答案 0 :(得分:5)

这并不像通常预期的那么简单。为了保证尾数的准确性,通常有两个值:

  1. 给出一个以十进制表示的值,如果从十进制转换为选定的二进制格式并返回(默认舍入),则可以保证保留多少个十进制数字。

  2. 给出二进制格式的值,如果将值转换为十进制格式并返回到原始二进制格式(同样,使用默认舍入),则需要多少个十进制数字即可。

在两种情况下,十进制表示均视为独立于使用的指数,没有前导和尾随零(例如,所有0.0123e4、1.23e2、1.2300e2、123、123.0、123000.000e-3均为3位数字)。

对于32位二进制浮点数,这两个大小分别为6和9个十进制数字。在C 中,它们是FLT_DIG和FLT_DECIMAL_DIG。 (这很奇怪,32位浮点数在所有数字的总和中都保留了7个十进制数字,但也有例外。) 在C ++中,分别查看std :: numeric_limits :: digits10和std :: numeric_limits :: max_digits10。

对于64位二进制浮点数,分别为15和17(分别为DBL_DIG和DBL_DECIMAL_DIG;以及std :: numeric_limits :: {digits10,max_digits10})。

它们的通用公式(thx2 @MarkDickinson)

  • $ {format} _DIG(digits10):floor((p-1)*log10(2))
  • $ {format} _DECIMAL_DIG(max_digits10):ceil(1+p*log10(2))

其中p是尾数的位数(对于标准化的IEEE754情况,其中包括隐藏的一位)。

此外,在C ++ numeric limits页上的注释以及一些数学解释:

  

标准的32位IEEE 754浮点类型具有24位小数部分(写了23位,暗含一个),这可能表明它可以表示7位小数(24 * std :: log10(2)为7.22),但是相对舍入误差是不一致的,并且某些具有7个十进制数字的浮点值无法转换为32位浮点数和返回值:最小的正例为8.589973e9,往返后变为8.589974e9。这些舍入误差不能超过表示中的一位,并且digits10的计算公式为(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

但是,在大多数系统上(我的系统是x86-84上的Ubuntu 18.04),float128的值令人困惑。它确实适用于具有64位有效位数的80位x86“扩展”浮点型;实际的IEEE754 float128具有112个有效位,因此实际值应为33,但numpy以此名称表示另一种类型。有关详细信息,请参见here:通常,float128是numpy中的错觉。

UPD3:您提到了float8-IEEE754集中没有这样的类型。可以想象这种类型用于完全特定的目的,但是对于任何通用用法,它的范围都太窄了。

相关问题