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

时间:2014-04-30 13:34:11

标签: java floating-point

以下是我正在看的内容:

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并没有真正帮助(至少我)。

我确实在the language spec中看到了这一点:

  

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

Wikipedia's IEEE 754 article给出了这个:

  

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

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

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

感谢您的帮助。

3 个答案:

答案 0 :(得分:6)

我认为这是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

答案 1 :(得分:4)

谢谢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);
}

以及其他一些链接以防其他人研究这些内容:

答案 2 :(得分:2)

来自JLS,4.2.4。浮点运算:

  

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

     

转换a时,Java编程语言使用舍入为零   将值浮动为整数(第5.1.3节),在这种情况下,其作用为   尽管数字被截断,但丢弃了尾数位。   向零舍入选择其结果格式的值最接近   与无限精确的结果相比,并没有更大的幅度。