float8、float16、float32、float64和float128能包含多少位数?

float8、float16、float32、float64和float128能包含多少位数?

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

给定以十进制表示形式表示的值,如果从十进制格式转换为选定的二进制格式并返回(带有默认四舍五入),那么有多少小数位可以被保证地保留下来。给定二进制格式的值,如果将值转换为十进制格式并返回到原始二进制格式(同样,带有默认舍入),则需要多少小数位数才能使原始值保持不变。在这两种情况下,十进制表示被视为独立于使用的指数,没有前导和尾随零(例如,所有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)

${格式}_DIG (digits10):floor((p-1)*log10(2))${格式}_DECIMAL_DIG (max_digits10):ceil(1+p*log10(2))其中p是尾数中的数字数(包括归一化IEEE754情况下的隐藏数字)。

此外,在C++ 数值极限页面上有一些数学解释的注释:

标准的32位IEEE 754浮点类型有一个24位小数部分(23位写入,一个隐含),这可能意味着它可以表示7位小数(24 *std: not 10(2)是7.22),但相对四舍五入误差是不一致的,有些浮点值带有7小数位数的浮点值不能被转换为32位浮点数和返回浮点数:最小的正例子是8.589973e9,这是往返后的8.589974e9。这些舍入错误在表示中不能超过一位,digits10计算为(24-1)*std::log10 10(2),即6.92。舍入结果为6。

在注释中查找16位和128位浮点数的值(但请参阅下面128位浮点数的实际值)。

对于指数,这是比较简单的,因为每个边界值(最小归一化、最小非正态化、最大值表示)都是精确的,可以很容易地获得和打印。

@PaulPanzer建议使用numpy.finfo。它首先给出这些值({format}_DIG);可能是您搜索的东西:

代码语言:javascript运行复制>>> 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上是Ubuntu18.04),float128的值令人困惑;它实际上是用于80位x86“扩展”浮点数,64位意义;real IEEE754 float128有112个意义和位,因此实值应该在33左右,但numpy在这个名称下显示了另一种类型。有关详细信息,请参阅这里:一般来说,float128是在numpy中的一种错觉。

UPD3:您提到了float8 -- IEEE754集中没有这样的类型。人们可以想象这种类型的某些完全特定的目的,但它的范围将过于狭窄,任何普遍使用。