Java Wierd导致使用string.format将浮点值格式化为字符串

Java Wierd导致使用string.format将浮点值格式化为字符串,java,floating-point,floating-accuracy,floating-point-conversion,Java,Floating Point,Floating Accuracy,Floating Point Conversion,我最近才来爪哇。 我大体上理解浮点精度和转换的问题,但不确定为什么我在Java中看到如此荒谬的结果。。。 我做了这个 String str1 = String.format("%.02f", 0.001921921f); String str2 = String.format("%.02f", 9.0921921f); String str3 = String.format("%.02f", 91.21921f); String str4 = String.format("%.02f", 911

我最近才来爪哇。 我大体上理解浮点精度和转换的问题,但不确定为什么我在Java中看到如此荒谬的结果。。。 我做了这个

String str1 = String.format("%.02f", 0.001921921f);
String str2 = String.format("%.02f", 9.0921921f);
String str3 = String.format("%.02f", 91.21921f);
String str4 = String.format("%.02f", 911212.09f); // WIERD: Prints 911212.06 !!!
String str5 = String.format("%.02f", 1212f); 
并在调试模式Eclipse debugger/Eclipse Platform 4.2.1/JavaSE6 MacMavericks OSX default中的字符串中看到了这些值

str1 = "0.00"
str2 = "9.09"
str3 = "91.22"
str4 = "911212.06"   ===> What the heck ?? Should be "911212.09" or some rounding of that?
str5 = "1212.00"
我一点也不明白。 让我解释一下我最终要做什么。。。 我有一堆输入浮点值,它们的小数精度不同,是从9.34、99.131等字符串转换而来的。 我想截断第二位以外的所有小数点,得到一个整数,所有数字都是整数。没有小数点,没有下限/上限/四舍五入等。19.2341将变成1923,19.2359也将变成1923,而不是1924。 现在我试着做一些事情,比如

int ival = (int)(float_val * 100.0);
但这存在精度/准确性问题。例如,如果浮点数包含17.3f,则IVA变为1729。 我认为使用格式化字符串可能会有所帮助,但这也会进行舍入,在尝试时,我还看到了上面的wierd案例。 知道我做错了什么吗? 现在,对于我的情况,我将只处理原始字符串值,以截断小数点并删除小数点,然后转换为int。

浮点有23位精度。要表示911212.09,在+0.005或-0.005范围内,需要27位,我可以关闭1位。因此,结果不一致也就不足为奇了

如果通过从数字文本中删除f来使用double,将获得52位精度,因此错误将足够小,在格式化为两位小数时不会影响结果

但是使用BigDecimal更好


顺便说一句,这不是Java或JDK的问题。它将出现在您尝试使用32位IEEE 754浮点类型的任何语言中。请阅读。

您的问题很简单,IEEE 754格式中描述的浮点的实习生表示不够精确,无法像您预期的那样处理911212.09f

它实际上只存储在32位值上,分布如下:

标志1位 8位表示指数,仅。。。 尾数是23位。 这只剩下23位精度,我们可以表示为最接近911212.09的浮点值实际上是911212.0625

通过阅读或使用此在线转换器,您可以更深入地了解这一切的工作原理:

正如中提到的@ajb,简单地使用double类型就可以对这个案例进行排序

i、 e:

//                                        removed 'f' here
//                                                v
System.out.println(String.format("%.02f", 911212.09));
。。。将输出:

911212.09

试试较新的jdk,如果它有差异,那么你会遇到一个错误如果你想要精度,使用BigDecimal。另外,将浮点值转换为int不会进行舍入,它会进行截断。我没有对任何东西进行否决。在进行诽谤之前,你应该小心你所做的假设。谢谢,这说明了这一点。在这种情况下使用double是可行的