当前位置: 首页 > 知识库问答 >
问题:

Java中的浮点精度和相等性

公羊英达
2023-03-14

众所周知,浮点数,即使是小数点后固定数字的十进制格式,也不能准确表示。所以我有以下程序要测试:

public class Main {
  public static void main(String[] args) {
    System.out.printf("0.1 in single precision is %.50f\n", 0.1f);
    System.out.printf("0.2 in single precision is %.50f\n", 0.2f);
    System.out.printf("0.3 in single precision is %.50f\n", 0.3f);
    System.out.printf("0.1 + 0.2 in single precision is %.50f\n", 0.1f + 0.2f);
    System.out.printf("0.1 + 0.2 == 0.3 is %b in single precision\n", 0.1123f * 0.4f + 0.2f * 0.5f == 0.2f * 0.7f + 0.0123f * 0.4f);

    System.out.println();

    System.out.printf("0.1 in double precision is %.50f\n", 0.1);
    System.out.printf("0.2 in double precision is %.50f\n", 0.2);
    System.out.printf("0.3 in double precision is %.50f\n", 0.3);
    System.out.printf("0.1 + 0.2 in double precision is %.50f\n", 0.1 + 0.2);
    System.out.printf("0.1 + 0.2 == 0.3 is %b in double precision\n", 0.1 + 0.2 == 0.3);
  }
}

输出如下:

0.1 in single precision is 0.10000000149011612000000000000000000000000000000000
0.2 in single precision is 0.20000000298023224000000000000000000000000000000000
0.3 in single precision is 0.30000001192092896000000000000000000000000000000000
0.1 + 0.2 in single precision is 0.30000001192092896000000000000000000000000000000000
0.1 + 0.2 == 0.3 is true in single precision

0.1 in double precision is 0.10000000000000000000000000000000000000000000000000
0.2 in double precision is 0.20000000000000000000000000000000000000000000000000
0.3 in double precision is 0.30000000000000000000000000000000000000000000000000
0.1 + 0.2 in double precision is 0.30000000000000004000000000000000000000000000000000
0.1 + 0.2 == 0.3 is false in double precision

以上结果中有两个问题我无法回答,我正在寻求帮助:

  1. 为什么0.1、0.2和0.3的双重表示看起来很精确,而0.1、0.2却不精确。

共有1个答案

严信瑞
2023-03-14
  1. 我怀疑这个系统。出来printf在此正常工作。要获得写入0.1时得到的精确值,可靠的方法是写入新的BigDecimal(0.1)。toString()
 类似资料:
  • 问题内容: 众所周知,即使是十进制格式的小数点后有固定数字的浮点数也无法准确表示。因此,我有以下程序要测试: 输出如下: 我无法从上述结果中回答两个问题,我正在寻求以下方面的帮助: 为什么使用的双重表示形式,并且看起来很精确,而没有。 为什么返回true? 问题答案: 我怀疑在这里不能正常工作。写入0.1时,获取确切值的一种可靠方法是write 。 “为什么0.1f + 0.2f == 0.3f返

  • 问题内容: 是否在任何地方都有Java库可以对IEEE 754半精度 数字执行计算或将其与双精度数字进行转换? 这些方法中的任何一种都是合适的: 将数字保持为半精度格式,并使用整数算术和位扭曲(如MicroFloat的单精度和双精度)进行计算 以单精度或双精度执行所有计算,转换成半精度以进行传输(在这种情况下,我需要经过良好测试的转换函数。) 编辑 :转换需要100%准确- 输入文件中 有 很多N

  • 运行以下代码时,我希望收到这样的输出: 但结果如下: 欢迎任何能指导我正确使用浮点比较和正确使用setprecision的建议。

  • 众所周知,在比较浮点值时必须小心。通常,我们不使用,而是使用一些基于epsilon或ULP的相等性测试。 然而,我想知道,当使用时,是否存在任何情况? 看看这个简单的片段,哪些案例可以保证成功? 注意:我已经检查了这个和这个,但是它们不包括我的(所有)病例。 注2:似乎我必须添加一些附加信息,因此答案在实践中可能很有用:我想知道: C标准的内容 这是我在当前标准草案中发现的唯一相关声明: 浮点类型

  • 问题内容: 如果我们运行以下代码: 它打印: 文字1.2345678990922222中的长尾将被忽略,但1.22222222222222222222中的长尾不会被忽略(变量d中的最后一个十进制数字变为3而不是2)。为什么? 问题答案: 打印a 或a 时看到的位数是Java的默认规则(从和转换为十进制)的结果。 Java的浮点数默认格式使用最少的有效十进制数字来将数字与附近的可表示数字区分开。1个