在Java中从double转换为float

时间:2023-01-28 11:10:05

If I'm working with a double, and I convert it to a float, how does this work exactly? Does the value get truncated so it fits into a float? Or does the value get rounded differently? Sorry if this sounds a bit remedial, but I'm trying to grasp the concept of float and double conversions.

如果我正在使用double,并将其转换为浮点数,那么它是如何工作的呢?该值是否被截断以便它适合浮点数?或者价值得到不同的结果?对不起,如果这听起来有点补救,但我正在努力掌握浮动和双重转换的概念。

2 个解决方案

#1


19  

From the Java Language Specification, section 5.1.3:

从Java语言规范,第5.1.3节:

A narrowing primitive conversion from double to float is governed by the IEEE 754 rounding rules (§4.2.4). This conversion can lose precision, but also lose range, resulting in a float zero from a nonzero double and a float infinity from a finite double. A double NaN is converted to a float NaN and a double infinity is converted to the same-signed float infinity.

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

and section 4.2.4 says:

和4.2.4节说:

The Java programming language requires that floating-point arithmetic behave as if every floating-point operator rounded its floating-point result to the result precision. Inexact results must be rounded to the representable value nearest to the infinitely precise result; if the two nearest representable values are equally near, the one with its least significant bit zero is chosen. This is the IEEE 754 standard's default rounding mode known as round to nearest.

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

#2


8  

I would suggest that floating-point types are most usefully regarded as representing ranges of values. The reason that 0.1f displays as 0.1 rather than as 0.100000001490116119384765625 is that it really represents the range of numbers from 13421772.5/134217728 to 13421773.5/134217728 (i.e. from 0.0999999977648258209228515625 to 0.1000000052154064178466796875); it wouldn't make sense to add extra digits indicating the number is greater than 0.100 when it might be less, nor to use a string of nines indicating the number is less than 0.100 when it might be greater.

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

Casting a double to a float will select the float whose range of values includes the range of doubles represented by the double. Note that while this operation is non-reversible, the result of the operation will generally be arithmetically correct; the only time it would not be 100% arithmetically correct would be if one were casting to float a double whose range was precisely centered on the boundary between two floats. In that situation, the system would select the float on one side or the other of the double's range; if the double in fact represented a number on the wrong side of the range, the resulting conversion would be slightly inaccurate.

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

In practice, the tiny imprecision mentioned above is almost never relevant, because the "range of values" represented by a floating-point type is in practice a little larger than indicated above. Performing a calculation (such as addition) on two numbers that have a certain amount of uncertainty will yield a result with more uncertainty, but the system won't keep track of how much uncertainty exists. Nonetheless, unless one performs dozens of operations on a float, or thousands of operations on a double, the amount of uncertainty will usually be small enough not to worry about.

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

It's important to note that casting a float to a double is actually far more dangerous operation than casting double to float, even though Java allows the former implicitly without a warning but squawks at the latter. Casting a float to a double causes the system to select the double whose range is centered about the center of the float's range. This will almost always result in a value whose actual uncertainty is far greater than would be typical of double-precision numbers. For example, if one casts 0.1f to double, the resulting double will represent a number in the range 0.10000000149011611 to 0.10000000149011613, even though the number it's supposed to be representing (one tenth) is, relatively speaking, nowhere near that range.

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

#1


19  

From the Java Language Specification, section 5.1.3:

从Java语言规范,第5.1.3节:

A narrowing primitive conversion from double to float is governed by the IEEE 754 rounding rules (§4.2.4). This conversion can lose precision, but also lose range, resulting in a float zero from a nonzero double and a float infinity from a finite double. A double NaN is converted to a float NaN and a double infinity is converted to the same-signed float infinity.

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

and section 4.2.4 says:

和4.2.4节说:

The Java programming language requires that floating-point arithmetic behave as if every floating-point operator rounded its floating-point result to the result precision. Inexact results must be rounded to the representable value nearest to the infinitely precise result; if the two nearest representable values are equally near, the one with its least significant bit zero is chosen. This is the IEEE 754 standard's default rounding mode known as round to nearest.

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

#2


8  

I would suggest that floating-point types are most usefully regarded as representing ranges of values. The reason that 0.1f displays as 0.1 rather than as 0.100000001490116119384765625 is that it really represents the range of numbers from 13421772.5/134217728 to 13421773.5/134217728 (i.e. from 0.0999999977648258209228515625 to 0.1000000052154064178466796875); it wouldn't make sense to add extra digits indicating the number is greater than 0.100 when it might be less, nor to use a string of nines indicating the number is less than 0.100 when it might be greater.

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

Casting a double to a float will select the float whose range of values includes the range of doubles represented by the double. Note that while this operation is non-reversible, the result of the operation will generally be arithmetically correct; the only time it would not be 100% arithmetically correct would be if one were casting to float a double whose range was precisely centered on the boundary between two floats. In that situation, the system would select the float on one side or the other of the double's range; if the double in fact represented a number on the wrong side of the range, the resulting conversion would be slightly inaccurate.

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

In practice, the tiny imprecision mentioned above is almost never relevant, because the "range of values" represented by a floating-point type is in practice a little larger than indicated above. Performing a calculation (such as addition) on two numbers that have a certain amount of uncertainty will yield a result with more uncertainty, but the system won't keep track of how much uncertainty exists. Nonetheless, unless one performs dozens of operations on a float, or thousands of operations on a double, the amount of uncertainty will usually be small enough not to worry about.

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

It's important to note that casting a float to a double is actually far more dangerous operation than casting double to float, even though Java allows the former implicitly without a warning but squawks at the latter. Casting a float to a double causes the system to select the double whose range is centered about the center of the float's range. This will almost always result in a value whose actual uncertainty is far greater than would be typical of double-precision numbers. For example, if one casts 0.1f to double, the resulting double will represent a number in the range 0.10000000149011611 to 0.10000000149011613, even though the number it's supposed to be representing (one tenth) is, relatively speaking, nowhere near that range.

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