在Java中从double转换为float

时间:2012-04-09 14:53:23

标签: java floating-point double type-conversion

如果我正在使用double,并将其转换为float,这是如何工作的?该值是否被截断以便它适合浮点数?或者价值得到不同的结果?很抱歉,如果这听起来有点补救,但我正在尝试掌握floatdouble次转化的概念。

2 个答案:

答案 0 :(得分:19)

来自Java Language Specification, section 5.1.3

  

从double到float的缩小基元转换由IEEE 754舍入规则(第4.2.4节)控制。这种转换可能会失去精度,但也会失去范围,导致从非零双精度浮点零和从有限双精度浮点无穷大。双NaN转换为浮点NaN,双无穷大转换为相同的浮点无穷大。

section 4.2.4说:

  

Java编程语言要求浮点运算表现得好像每个浮点运算符将其浮点结果四舍五入到结果精度。不精确的结果必须四舍五入到最接近无限精确结果的可表示值;如果两个最接近的可表示值相等,则选择具有最低有效位的值。这是IEEE 754标准的默认舍入模式,称为舍入到最近。

答案 1 :(得分:9)

我建议将浮点类型最有效地视为表示值的范围。 0.1f显示为0.1而不是0.100000001490116119384765625的原因是它实际上代表从13421772.5 / 134217728到13421773.5 / 134217728(即从0.0999999977648258209228515625到0.1000000052154064178466796875)的数字范围;添加额外的数字表示数字大于0.100可能没有意义,也不会使用一串表示数字小于0.100的数字可能更大。

将double转换为float将选择float,其值范围包括double表示的双精度范围。请注意,虽然此操作是不可逆的,但操作的结果通常是算术正确的;唯一一次,它不是100%算术正确的,如果一个人正在施放浮动一个双精度,其范围正好在两个浮标之间的边界上。在那种情况下,系统会选择浮动的一侧或另一侧的双重范围;如果double实际上表示该范围的错误一侧的数字,则所得到的转换将略微不准确。

在实践中,上面提到的微小不精确几乎从不相关,因为浮点类型所代表的“值范围”实际上比上面指出的要大一些。对具有一定不确定性的两个数字执行计算(例如加法)将产生具有更多不确定性的结果,但系统将不会跟踪存在多少不确定性。尽管如此,除非一个人在浮动上执行数十次操作,或者对一次操作执行数千次操作,否则不确定性的数量通常会小到不用担心。

重要的是要注意,将float转换为double实际上比将double转换为float更危险,即使Java允许前者隐式没有警告而是对后者发出警告。将浮点数转换为double会导致系统选择其范围以浮点范围的中心为中心的double。这几乎总会产生一个值,其实际不确定性远远大于双精度数的典型值。例如,如果一个将0.1f转换为double,则得到的double将表示0.10000000149011611到0.10000000149011613范围内的数字,即使它应该代表的数字(十分之一)相对来说也不在该范围附近。