Java中的浮点数和双精度数有多少个有效数字?


81

浮点数是否具有32个二进制数字,双精度数是否具有64个二进制数字?该文档太难理解了。

所有位都转换为有效数字吗?还是小数点的位置占用了一些位?


2
所有这些位都转换为有效数字吗?还是小数点的位置占用了一些位?
Eamon Moloney 2012年

@ user1774214浮点数根本没有像整数那样编码。看看我给的链接。例如,您必须了解精度不统一。
DenysSéguret12年

@dystroy我不确定“精度不统一”是什么意思。除非您指的是非正规数,否则它的统一精度为53位和24位。
Pascal Cuoq 2014年

2
@PascalCuoq对于较小的数字,精度更高。随着指数变化(或点浮动),尾数保持代表相同数量的数字。因此,如果数字很大,则尾数会“无法达到”较低的有效数字,从而降低精度。
Vituel 2015年

3
@Virtuel精度为53位。就是我们所说的精度。您似乎在考虑绝对准确性或其他问题。
Pascal Cuoq 2015年

Answers:


105

float32位(4字节),其中23位用于尾数(约7个十进制数字)。指数使用8位,因此浮点数可以使用这8位将小数点“移”到右边或左边。这样做避免了像0.0000003(3×10 -7)或3000000(3×10 7)那样在尾数中存储大量零。有1位用作符号位。

double64位(8个字节),其中52位用于尾数(约16个十进制数字)。指数使用11位,符号位使用1位。

由于我们使用的是二进制数(只有0和1),所以当数字不为零时,尾数中的一位隐式为1(使用浮点和重复使用此技巧)。

另外,由于所有内容均为二进制(尾数和指数),因此通常无法精确转换为十进制数。像0.5、0.25、0.75、0.125这样的数字会被精确存储,而不会存储0.1。正如其他人所说,如果您需要精确存储美分,请不要使用float或double,而应使用int,long,BigInteger或BigDecimal。

资料来源:

http://en.wikipedia.org/wiki/Floating_point#IEEE_754:_floating_point_in_modern_computers

http://en.wikipedia.org/wiki/Binary64

http://en.wikipedia.org/wiki/Binary32


6到9是什么意思?怎么改变?因此,如果我多次运行某些代码,这些代码有8个十进制数字,例如0.000000001,我会得到不同的结果吗?你是这个意思吗?
Aequitas

1
一些数字可以比其他数字更精确地表示。您可以看到0.125(1/8,八是2的幂)与0.1(1/10,十不是二的幂)之间的差。前者有更多(十进制)数字,但表示准确。因此,十进制数字为6的数字可能比另一数字为8的数字具有更大的舍入误差。
marcus

9
15.9的十进制数字double和的7.2 float,即15和7。在每​​种情况下都可以表示一些较大的数字,并且都不适用于分数,但是没有“平均值”,并且您的消息来源都没有说除此以外。
罗恩侯爵

1
如果您不喜欢平均值一词,请提出修改。它不是我最初添加的,而是由其他人编辑的(而且我真的没有看到进行此编辑的必要)。
marcus

4
有趣的是,实际上精确度比尾数/有效位数中存储的位数还要高。23和52位分别存储为float和double,但是由于数字已标准化,我们可以假设前导1位,然后忽略它。这就是为什么有效精度分别为24位和53位的原因。计算精确的十进制精度log10(2 ^ 24)= 7.22和log10(2 ^ 53)= 15.95
Georgie

32

32位浮点数的精度约为7位,而64位双精度数的精度约为16位。

长答案:

浮点数具有三个组成部分:

  1. 一个符号位,确定数字是正数还是负数。
  2. 一个指数,确定数量的大小
  3. 一个小数,它确定数字在两个指数值之间的距离。有时称为“有效位数,尾数或系数”

本质上,这可以解决sign * 2^exponent * (1 + fraction)。指数的数字“大小”与我们无关,因为它仅缩放小数部分的值。知道log₁₀(n)给出的位数n,†,我们可以确定浮点数的精度log₁₀(largest_possible_fraction)。因为浮点数中的每个位都存储2种可能性,所以二进制数n位最多可以存储一个数字2ⁿ - 12ⁿ 的总和,其中一个值为零)。这会有点麻烦,因为事实证明,浮点数存储时使用的分数比其使用的位数少,因为特别表示了零,并且所有非零数字都至少具有一个非零二进制位。

与此相结合,浮点数的精度位数为 log₁₀(2ⁿ),其中n是浮点数的分数的位数。一个32位浮点数具有24位小数,其精度约为7.22个十进制数字,而一个64位双精度数具有53位的分数,其精度为≈15.95个十进制数字。

有关浮点精度的更多信息,您可能需要阅读有关机器epsilon的概念。


n ≥ 1至少-对于其他数字,您的公式将更像 ⌊log₁₀(|n|)⌋ + 1

‡“此规则被不同地称为前导位约定,隐式位约定或隐藏位约定。” (维基百科


17

java规范

浮点类型为float和double,它们在概念上与IEEE二进制浮点算术标准ANSI / IEEE中指定的单精度32位和双精度64位格式IEEE 754值和操作相关联标准754-1985(纽约,IEEE)。

在不了解IEEE754基础知识的情况下,很难对数字做任何事情,因此这是另一个链接

重要的是要了解精度不是统一的,并且这并不是整数的精确存储。

一个例子 :

double a = 0.3 - 0.1;
System.out.println(a);          

版画

0.19999999999999998

如果您需要任意精度(例如出于财务目的),则可能需要Big Decimal


7

正常的数学答案。

理解将浮点数实现为一些代表指数的位,其余的代表数字(在二进制系统中),大多数情况如下:

如果更改了最低有效位,则指数较高,例如10²³,两个相邻的可分辨数字之间会出现很大的差异。此外,以2为底的小数点使得只能近似以10为基数。1 / 5,1 / 10是无尽的数字。

因此,一般而言:如果您关心有效数字,则不应使用浮点数。对于具有计算e的货币金额,最好使用BigDecimal

对于物理浮点倍数就足够了,几乎没有浮点数。此外,处理器的浮点部分FPU甚至可以在内部使用更多的精度。


3

浮点数使用指数形式进行编码m * b ^ e,即类似,即完全不像整数。您提出的问题在定点数的背景下将是有意义的。有许多可用的定点算法库

关于浮点运算:小数位数取决于表示形式和数字系统。例如,有些周期数(0.33333)的十进制表示形式不是有限的,但是二进制形式的表示形式是有限的,反之亦然。

还值得一提的是,由于不能使用,,和进行编码,直到某个点的浮点数的差值确实大于1,即value + 1yields 。小于1的值会发生相同的情况,即所有可能的代码点的距离都不相同。valuevalue + 1m * b ^ embe

因此,没有n像定点数字那样精确的数字精度,因为并非每个带有n小数位的数字都具有IEEE编码。

有一份几乎是强制性的文档,您应该阅读然后解释浮点数: 每位计算机科学家都应该了解浮点算术


2
+1提及“每个计算机科学家都应了解的浮点算术知识”。但是,值得注意的是,每个具有有限二进制小数表示形式的数字也都具有有限的十进制表示形式。问题仅从十进制变为二进制。
Patricia Shanahan 2012年

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.