Java如何将浮点数转换为字符串

这是我正在看的东西:

float p=1.15f; BigDecimal bdp=new BigDecimal(p); float q=1.1499999f; float r=1.14999999f; System.out.println(p); //1.15 System.out.println(bdp); //1.14999997615814208984375 System.out.println(q); //1.1499999 System.out.println(r); //1.15 

所以我理解“p”1.15的十进制值不能用二进制表示。
所以大的十进制“bdp”输出对我来说很有意义……这就是浮点数的实际值。

问题1
当浮点“p”转换回字符串以进行输出时(如1.15),舍入的方式/位置(从内部1.149..375到1.15)?

它在文档中指定了哪里? toString javadoc并没有真正的帮助(至少我)。

我确实在语言规范中看到了这个:

float和double类型的元素是可以分别使用IEEE 754 32位单精度和64位双精度二进制浮点格式表示的值。

维基百科的IEEE 754文章给出了这样的结论 :

这给出了6到9个有效十进制数字精度(如果一个十进制字符串最多有6个有效小数被转换为IEEE 754单精度,然后转换回相同数量的有效小数,则最终字符串应与原始字符串匹配;

问题2
所以这似乎是Java / IEEE 754浮点数应该如何工作?

我保证浮点/字符串转换/表示的准确性达到一定数量的数字(如“p”和“q”),如果超过这个数字,Java将进行一些舍入显示(如“r”) “)?

感谢帮助。

来自JLS,4.2.4。 浮点运算:

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

当将浮点值转换为整数(第5.1.3节)时,Java编程语言使用舍入为零,在这种情况下,该行为就好像数字被截断一样,丢弃了尾数位。 向零舍入选择其结果,格式的值最接近并且在幅度上不大于无限精确的结果。

我认为这是Javadoc的相关部分,它描述了您正在查看的行为(来自static String toString(float)方法):

m或a的小数部分必须打印多少位? 必须至少有一个数字来表示小数部分,并且除此之外必须有多个,但只有多少个,更多的数字才能唯一地将参数值与float类型的相邻值区分开来。

换句话说:浮点类型的toString方法通常会产生最短的十进制表示,可以无差别地识别浮点数的真值。

示例程序说明:

 import java.math.BigDecimal; public class FloatTest { static void show(float f) { BigDecimal f_exact = new BigDecimal(f); System.out.println("---"); System.out.println("String value: " + f); System.out.println("Exact value: " + f_exact); System.out.println("Delta: " + new BigDecimal("1.15").subtract(f_exact)); } public static void main(String[] args) { show(1.15f); show(Math.nextUp(1.15f)); } } 

输出:

 --- String value: 1.15 Exact value: 1.14999997615814208984375 Delta: 2.384185791015625E-8 --- String value: 1.1500001 Exact value: 1.150000095367431640625 Delta: -9.5367431640625E-8 

谢谢mttdbrd ……这有帮助。 从你的第一段开始,我认为我的问题的答案是:是的,Java根据IEEE规范在内部进行四舍五入。

这是一个程序的输出,让我看一下这个四舍五入的行动:

 ------------------------------------------- string 1.49999 bigdec of float 1.499989986419677734375 float back to str 1.49999 ------------------------------------------- string 1.4999991 bigdec of float 1.49999904632568359375 float back to str 1.499999 ------------------------------------------- string 1.4999992 bigdec of float 1.49999916553497314453125 float back to str 1.4999992 ------------------------------------------- string 1.4999993 bigdec of float 1.4999992847442626953125 float back to str 1.4999993 ------------------------------------------- string 1.4999994 bigdec of float 1.49999940395355224609375 float back to str 1.4999994 ------------------------------------------- string 1.4999995 bigdec of float 1.499999523162841796875 float back to str 1.4999995 ------------------------------------------- string 1.4999996 bigdec of float 1.49999964237213134765625 float back to str 1.4999996 ------------------------------------------- string 1.4999997 bigdec of float 1.49999964237213134765625 float back to str 1.4999996 ------------------------------------------- string 1.4999998 bigdec of float 1.4999997615814208984375 float back to str 1.4999998 ------------------------------------------- string 1.4999999 bigdec of float 1.49999988079071044921875 float back to str 1.4999999 ------------------------------------------- string 1.15 bigdec of float 1.14999997615814208984375 float back to str 1.15 ------------------------------------------- string 1.49999964237213134765626 bigdec of float 1.49999964237213134765625 float back to str 1.4999996 

这是程序,如果有人想要它:

 public static void floatAccuracy3() { printFloatAndBigDec("1.49999"); for (int i = 1; i < 10; i++) { String s="1.499999"; s+=i; printFloatAndBigDec(s); } printFloatAndBigDec("1.15"); printFloatAndBigDec("1.49999964237213134765626"); } public static void printFloatAndBigDec(String s) { Float f=new Float(s); BigDecimal bdf=new BigDecimal(f); System.out.println("-------------------------------------------"); System.out.println("string "+s); System.out.println("bigdec of float "+bdf); System.out.println("float back to str "+f); } 

还有其他一些链接,以防它们对研究这些东西的其他人有所帮助:

  • 浮点基础知识
  • princeton cs介绍浮点数
  • 每个计算机科学家应该知道的浮点运算
  • 为什么0.1在浮点中不存在
  • JLS 4.2.4浮点运算
  • IEEE舍入到最近