我有以下代码,我想为float指定一个十进制值而不会丢失精度。
String s1= "525.880005";
Float f = new Float(s1);
System.out.println(f);
输出: 5.88
预期输出 525.880005
答案 0 :(得分:5)
Float
只有7-8个有效数字的精度。您的示例中的“5”是第9位。
即使它具有足够的精度,我也不知道525.880005是否可以完全表示为二进制浮点数。大多数小数值不是:)
如果确切的十进制表示对您很重要,则应使用BigDecimal
。
答案 1 :(得分:2)
这个问题隐含着一个真正的矛盾:
分配给浮动< - >精确度
525.880005是这个float-domain中最接近525.88的数字。
浮动数字无法映射到所有数字的原因是分数的十进制和二进制系统之间的不匹配。
其他类型,如十进制和金钱,使用其他更多内存消耗技术来存储数字(例如,在一个字符串中,您可以存储任何数字,但当然这不是最有效的方法数学)
一个简单的例子:我自己的二元系统中的0.3:
0.1b (inary) would be 0.5 d (ecimal) so too much...
0.01b --> 0.25d (1/4 too little)
0.011 --> 0.375 (1/4 + 1/8 too much)
0.0101 --> 0.3125 (1/4 + 1/16 still too much)
...
0.010011 --> 1/4 +1/32 + 1/64 = 0.296875
假设我的系统有6位表示分数,0.296875将是该域最接近的。由于十进制/二进制系统,无法访问正确的数字。
有关示例,请参阅: Floating point inaccuracy examples
在这里可以找到你的问题的精彩阐述: http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html
另一个注意事项:它实际上是关于不匹配,而不是关于系统的“质量”:例如,在十进制表示法中,您不能表示1/3 100%准确,而这在其他系统中是完全可能的。
答案 2 :(得分:1)
float
类型无法保存所有可能的值(double
也不能)。如果您是从字符串中进行分配,则可能更喜欢BigDecimal
,因为BigDecimal
可以精确地保存您可以用字符串合理表示的任何内容。
请注意,BigDecimal
也无法保存所有可能的值(例如,由于我们无法写入1/3的相同原因,它无法精确地表示1/3 < em>精确在我们的十进制表示系统中 - 它永远不会结束)。但同样,如果您的来源是字符串值,那么BigDecimal
将比float
或double
更接近您的可能值。当然,这是一个成本。 float
和double
的计算速度非常快; BigDecimal
设计为非常精确的十进制值,代价是速度。
答案 3 :(得分:0)
Float
没有足够的有效数字来表示你的电话号码。试试Double
。