以下是我正在看的内容:
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”)?
感谢您的帮助。
答案 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节),在这种情况下,其作用为 尽管数字被截断,但丢弃了尾数位。 向零舍入选择其结果格式的值最接近 与无限精确的结果相比,并没有更大的幅度。