在Java中有多less有效数字有浮点数和双精度?

浮点数是否有32个二进制数字,而一个double是否有64个二进制数字? 文件太难理解了。

所有的位都翻译成有效数字吗? 或者小数点的位置占用了一些位?

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

来自java规范 :

浮点types是float和double,它们在概念上与单精度32位和双精度64位格式的IEEE 754值和在IEEE标准中针对二进制浮点运算ANSI / IEEE标准754-1985(IEEE,纽约)。

由于在不了解IEEE754基础知识的情况下很难对数字进行任何操作,这里还有一个链接 。

理解精度不统一是很重要的,这不像整数那样精确地存储数字。

一个例子 :

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

版画

 0.19999999999999998 

如果你需要任意精度(例如为了财务目的),你可能需要大十进制 。

一个正常的math答案。

理解浮点数被实现为表示指数和其余部分的一些比特,大部分用于数字(在二进制系统中),具有以下情形:

如果最低有效位被改变,则指数很高,例如10 23,两个相邻的可变数字之间会出现很大的差异。 此外,基数2的小数点使得许多基数10的数字只能近似; 1/5,1/10是无止境的数字。

所以一般来说 :如果你关心有效数字,不应该使用浮点数。 对于计算的金额,e,a,最好使用BigDecimal

对于物理浮点双打是足够的, 浮动几乎从来没有。 此外,处理器的浮点部分FPU甚至可以在内部使用更多的精确度。

浮点数使用指数forms编码,就像m * b ^ e ,即不像整数。 您提出的问题在定点数字的背景下将是有意义的。 有许多定点算术库可用。

关于浮点运算:小数位数取决于演示文稿和数字系统。 例如,有周期性数字( 0.33333 ),它没有十进制的有限表示,但有一个在二进制中,反之亦然。

另外值得一提的是,直到某一点的浮点数确实有一个大于1的差值,即value + 1产生value ,因为value + 1不能用m * b ^ e编码,其中mbe是固定的长度。 对于小于1的值也是如此,即所有可能的码点不具有相同的距离。

正因为如此,像定点数字一样,没有精确的n数字,因为不是每个具有n十进制数字的数字都有IEEE编码。

有一个几乎是必须的文件,你应该阅读然后解释浮点数字: 每个计算机科学家应该知道的浮点运算 。

看看Float.intBitsToFloatDouble.longBitsToDouble ,这些解释了位如何对应于浮点数。 特别是,正常的float看起来像这样

  s * 2^exp * 1.ABCDEFGHIJKLMNOPQRSTUVW 

其中A … W是23比特 – 0和1 – 表示二进制中的分数 – s是+/- 1,分别由0或1表示,exp是有符号的8比特整数。

如果我们看看最小正浮点值。

 Float.MIN_VALUE = 1.4E-45f; // 0.000000000000000000000000000000000000000000001401298464324817 

所以在技术上float可以保持60个值,因此对于(1和-1)之间的范围,你可能只想使用44个地方。

对于一般的目的,我喜欢留在9995.9995和-9995.9995之间,最低精度为0.0001。

为了好玩,你可以尝试:

System.out.println(new DecimalFormat("#####.#####").format(9996.9996f));

Result: 9997

如果我们看一下最小正双精度值。

 Double.MIN_Value = 4.9E-324; // 0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000049 

所以在技术上double可以容纳326个值,因此对于(1和-1)之间的范围,你可能只想使用324个地方。