2011-04-18 43 views
1

我有下面的代码,我想分配一个十进制值来浮动而不会失去精度。从字符串分配到精度浮点数

String s1= "525.880005"; 
Float f = new Float(s1); 
System.out.println(f); 

输出: 5.88

预期输出: 525.880005

+0

如果使用.parseFloat()方法会发生什么? – reporter 2011-04-18 14:16:02

+0

@reporter:他实际上是。 'Float'构造函数和'parseFloat'都使用'Float.valueOf(String)'执行的转换。所以这是相同的转换。更多信息:http://download.oracle.com/javase/6/docs/api/java/lang/Float.html – 2011-04-18 14:20:58

回答

5

Float只具有精度7-8显著数字。你例子中的“5”是第9位数字。

即使它有足够的精度,我也不知道525.880005是否可以完全表示为二进制浮点数。大多数小数值不是:)

如果确切的十进制表示对您很重要,您应该使用BigDecimal

1

float类型不能容纳所有可能的值(也不可能double)。如果您使用字符串进行分配,您可能更愿意使用BigDecimal,因为BigDecimal可以精确地容纳任何可以用字符串合理表示的内容。

注意BigDecimal并不都可能值(它不能准确地代表1/3,例如,出于同样的原因,我们不能在我们的十进制表示系统 写1/3 正是它不会结束)。但是,如果您的来源是字符串值,则BigDecimal将与您的可能值更接近,比floatdouble更符合您的来源。当然,这是一个成本。 floatdouble被设计为计算速度非常快; BigDecimal被设计成十分精确的十进制值,代价是速度。

0

Float没有足够的有效数字来表示您的号码。尝试Double

2

有没有在这个问题隐含一个真正的矛盾:

分配浮动< - >室内用精密

525.880005是绝对在这个浮动域最接近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

而且你的问题一个很好的精心explenation是在这里找到: http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html

另注:这是真正关心的失配,而不是关于“质量”系统:例如,用十进制表示法,不能将1/3表示为100%准确,而在其他系统中这是完全可能的。