2009-10-30 56 views
20

Java中float和double的包含范围是什么?Java中float和double的包含范围是什么?

为什么不建议float或double用于精度要求严格的任何事情?

+4

引用了关于不使用float或double的特别之处在于句话 “为重要的东西”? – 2009-10-30 15:35:02

+6

你在标题和正文中提出了两个不同的问题。一次提出一个问题,并花时间写一个完整的问题。 – GEOCHET 2009-10-30 15:48:46

+1

是的,但'不确切'并不意味着'不重要'。如果某些内容对性能至关重要,而不是精确至关重要,那么浮点是比BigDecimal更好的选择。 – Joren 2009-10-30 15:49:53

回答

20

Java的Double类的成员包含该类型的最小值和最大值。

2^-1074 <= x <= (2-2^-52)·2^1023 // where x is the double. 

退房的DoubleMin_VALUEMAX_VALUE静态最终成员。 (一些)人们会建议不要将浮点类型用于准确性和精确性至关重要的事情,因为舍入错误可能会通过可测量(小)量来推断计算。

+8

不要忘记,一些数字只是不能用浮点数或双精度表示。标准的例子是想象一个银行应用程序,你从2.00美元撤回1.10美元。使用双打的结果是$ 0。899999999999999,由于类似能力代表1.1在双倍。 – 2009-10-30 16:25:16

+1

...这就是为什么你应该总是使用BigDecimal来表示货币类型(或者更一般的意义上,精确的小数)。 – 2009-10-30 17:03:37

+5

@dtsazza - 不需要使用BigDecimal,您也可以使用整数类型,并以美分(而非分数美元)表示数字。关键是你不能因为精度有限而使用float或double来赚钱。 – Jesper 2009-10-30 22:18:59

3

当然,您可以使用浮点数或双精度来处理“关键”的事情......许多应用程序除了使用这些数据类型关键字之外什么也不做。

您可能会误解某些关于浮点数的警告,例如建议不要使用compare for exact equality等等。

5

Primitives Data Types

  • float:float数据类型是单精度32位IEEE 754 浮点。其值范围是 超出了本讨论的范围, ,但在Java语言规范的部分4.2.3 中指定。至于 与byteshort的建议,使用(而不是 double)一float如果你需要节省内存 浮点 很多大的数组。此数据类型不应使用 作为精确值,例如 货币。为此,您需要 而不是使用java.math.BigDecimal 类。 Numbers and Strings涵盖了BigDecimal和 其他有用的类,由 Java平台提供。

  • double:本double数据类型是双精度64位IEEE 754 浮点。其值范围是 超出了本讨论的范围, ,但在Java语言规范的部分4.2.3 中指定。 对于十进制值,此数据类型通常是默认选项 。由于上面提到的 ,此数据类型应该不会用于精确的值,如 作为货币。

对于值的范围,请参阅JLS的部分4.2.3 Floating-Point Types, Formats, and Values

+1

你没有在JLS中找到你的答案吗? – 2009-10-30 15:48:56

8

二进制浮点数具有令人感兴趣的精度特性,因为该值存储为二进制整数,该二进制整数升至二进制功率。当处理子整数值(即0到1之间的值)时,两个“四舍五入”的负幂与十负负幂非常不同。

例如,数字0.1可以表示为1 x 10 -1,但是没有可以精确表示0.1的基数2指数和尾数的组合 - 最接近的是0.10000000000000001。

所以,如果你有一个应用程序,你正在使用像0.1或0.01这样的值是一个很大的问题,但是小的(小于0.000000000000001%)错误是不能容忍的,那么二进制浮点数不适合你。相反,如果十次幂对您的应用程序不是“特殊的”(十次幂在货币计算中很重要,但不是在物理学的大多数应用中),那么实际上使用二进制浮点运算点,因为它通常至少快一个数量级,而且它的内存效率要高得多。

来自Python文档floating point issues and limitations的文章在以易于理解的形式解释此问题方面表现出色。维基百科也有一篇关于floating point的好文章,它解释了表示背后的数学。

+0

链接非常有用谢谢 – DeltaCap 2015-08-09 02:45:22

18

Java的基本数据类型

布尔: 1位。可能只有真值和假值。

字节: 1个带符号的字节(二进制补码)。覆盖从-128到127

短值: 2个字节,符号(2的补码),-32,768至32,767

INT: 4个字节,符号(2的补码)。 -2,147,483,648至2,147,483,647。

long: 8字节有符号(二进制补码)。范围从-9,223,372,036,854,775,808到+9,223,372,036,854,775,807。

float: 4字节,IEEE 754.涵盖从1.40129846432481707e-45到3.40282346638528860e + 38(正数或负数)的范围。

double: 8字节IEEE 754.覆盖范围从4.94065645841246544e-324d到1.79769313486231570e + 308d(正值或负值)。

字符: 2个字节,无符号,Unicode的,0到65,535