简体   繁体   English

将1234567.1234的双精度值转换为Java中的float

[英]Converting double value of 1234567.1234 to float in java

I am trying to convert double to float in java. 我正在尝试将double转换为java中的float。

Double d = 1234567.1234;
Float f = d.floatValue();

I see that the value of f is 我看到f的值是

1234567.1

I am not trying to print a string value of float. 我不尝试打印float的字符串值。 I just wonder what is the maximum number of digits not to lose any precision when converting double to float. 我只是想知道将double转换为float时不失去任何精度的最大位数是多少。 Can i show more than 8 significant digits in java? 我可以在Java中显示超过8位有效数字吗?

float : 32 bits (4 bytes) where 23 bits are used for the mantissa (6 to 9 decimal digits, about 7 on average ). float32位 (4字节),其中23位用于尾数(6到9个十进制数字, 平均约7 )。 8 bits are used for the exponent, so a float can “move” the decimal point to the right or to the left using those 8 bits. 指数使用8位,因此浮点数可以使用这8位将小数点“移动”到右边或左边。 Doing so avoids storing lots of zeros in the mantissa as in 0.0000003 (3 × 10 -7 ) or 3000000 (3 × 10 7 ). 这样做避免了像0.0000003(3×10 -7 )或3000000(3×10 7 )一样在尾数中存储大量零。 There is 1 bit used as the sign bit. 有1位用作符号位。

double : 64 bits (8 bytes) where 52 bits are used for the mantissa (15 to 17 decimal digits, about 16 on average ). double64位 (8字节),其中52位用于尾数(15到17个十进制数字, 平均约16 )。 11 bits are used for the exponent and 1 bit is the sign bit. 指数使用11位,符号位使用1位。

I believe you hit this limit what cause that problem. 我相信您达到此限制是什么原因导致了该问题。

If you change 如果你改变

Double d = 123456789.1234;
Float f = d.floatValue();

You will see that float value will be 1.23456792E8 您将看到float值为1.23456792E8

The precision of a float is about 7 decimals, but since floats are stored in binary, that's an approximation. float的精度约为 7位小数,但是由于浮点数以二进制形式存储,因此为近似值。

To illustrate the actual precision of the float value in question, try this: 为了说明所涉及的浮点值的实际精度,请尝试以下操作:

double d = 1234567.1234;
float f = (float)d;
System.out.printf("%.9f%n", d);
System.out.printf("%.9f%n", Math.nextDown(f));
System.out.printf("%.9f%n", f);
System.out.printf("%.9f%n", Math.nextUp(f));

Output 输出量

1234567.123400000
1234567.000000000
1234567.125000000
1234567.250000000

As you can see, the effective decimal precision is about 1 decimal place for this number, or 8 digits, but if you ran the code with the number 9876543.9876 , you get: 如您所见,该数字的有效十进制精度约为 1个小数位,即8位数字,但是如果您运行的数字为9876543.9876 ,则会得到:

9876543.987600000
9876543.000000000
9876544.000000000
9876545.000000000

That's only 7 digits of precision. 精度只有7位数字。

I just wonder what is the maximum number of digits not to lose any precision when converting double to float. 我只是想知道将double转换为float时不失去任何精度的最大位数是多少。

Maybe you don't realize it, but the concept of N digits precisions is already ambigous. 也许您没有意识到,但是N位精度的概念已经模棱两可。 Doubtlessly you meant "N digits precision in base 10 ". 毫无疑问,您的意思是“ 以10为底的 N位精度”。 But unlike humans, our computers work with Base 2. 但是与人类不同,我们的计算机可与Base 2配合使用。

Its not possible to convert every number from Base X to Base Y (with a limited amount of retained digits) without loss of precision, eg the value of 1/3rd is perfectly accurately representable in Base 3 as "0.1". 不可能在不损失精度的情况下将所有数字从基数X转换为基数Y(具有有限的保留位数),例如1 / 3rd的值在基数3中可以完全准确地表示为“ 0.1”。 In Base 10 it has an infinite number of digits 0.3333333333333... Likewise, commonly perfectly representable numbers in Base 10, eg 0.1 need an infinite number of digits to be represented in Base 2. On the other hand, 0.5 (Base 10) is peferectly accurately representable as 0.1 (Base 2). 在Base 10中,它具有无数个数字0.3333333333333 ...同样,在Base 10中通常可以完美表示的数字,例如0.1需要在Base 2中表示无数个数字。另一方面,0.5(Base 10)是准确地表示为0.1(基数2)。

So back to 回到

I just wonder what is the maximum number of digits not to lose any precision when converting double to float. 我只是想知道将double转换为float时不失去任何精度的最大位数是多少。

The answer is "it depends on the value". 答案是“取决于价值”。 The commonly cited rule of thumb "float has about 6 to 7 digits decimal precision" is just an approximation. 通常引用的经验法则“浮点数大约有6到7位十进制精度”只是一个近似值。 It can be much more or much less depending on the value. 取决于该值,它可以更多或更少。

When dealing with floating point the concept of relative accuracy is more useful, stop thinking about "digits" and replace it with relative error. 当处理浮点时,相对精度的概念会更有用,请停止考虑“数字”,而用相对误差代替。 Any number N (in range) is representable with an error of (at most) N / accuracy, and the accuracy is the number of mantissa bits in the chosen format (eg 23 (+1) for float, 52 (+1) for double). 可以表示任何数量的N(范围内),最大误差为N /精度,精度是所选格式的尾数位数(例如,浮点数为23(+1),浮点数为52(+1))双)。 So a decimal number represented as a float is has a maximum approximation error of N / pow(2, 24). 因此,以浮点数表示的十进制数的最大近似误差为N / pow(2,24)。 The error may be less, even zero, but it is never greater. 误差可能较小,甚至为零,但永远不会大于。

The 23+1 comes from the convention that floating point numbers are organized with the exponent chosen such that the first mantissa bit is always a 1 (whenever possible), so it doesn't need to be explicitly stored. 23 + 1来自以下约定:浮点数是根据所选的指数进行组织的,因此第一个尾数位始终为1(如果可能),因此不需要显式存储它。 The number of physically stored bits, eg 23 thus allows for one extra bit of accuracy. 因此,物理存储的位数(例如23)可以增加一位精度。 (There is an exceptional case where "whenever possible" does not apply, but lets ignore that here). (在特殊情况下,“只要可能”不适用,但在此忽略它)。

TL;DR : There is no fixed number of decimal digits accuracy in float or double. TL; DR :浮点数双精度数没有固定的十进制数字精度。

This is a simple example in support of the view that there is no safe number of decimal digits. 这是一个简单的示例,它支持没有安全的十进制数字的观点。

Consider 0.1. 考虑0.1。

The closest IEEE 754 64-bit binary floating point number has exact value 0.1000000000000000055511151231257827021181583404541015625. 最接近的IEEE 754 64位二进制浮点数具有精确值0.1000000000000000055511151231257827021181583404541015625。 It converts to 32-bit binary floating point as 0.100000001490116119384765625, which is considerably further from 0.1. 它将转换为32位二进制浮点,格式为0.100000001490116119384765625,该值与0.1相比要远得多。

There can be loss of precision with even a single significant digit and single decimal place. 即使只有一个有效数字和一个小数位,也可能会失去精度。

Unless you really need the compactness of float, and have very relaxed precision requirements, it is generally better to just stick with double. 除非您真的需要浮子的紧凑性,并且对精度有非常宽松的要求,否则通常最好坚持使用双精度。

EDIT. 编辑。
No you cannot get any more precise with a float in Java because floats can only contain 32 bits ( 4 bytes). 不,在Java中使用浮点数无法获得任何更精确的信息,因为浮点数只能包含32位(4个字节)。 If you want more precision, then continue to use the Double. 如果要提高精度,请继续使用Double。 This might also be helpful 可能也有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM