对于Java程序,我编写了一个计算两个浮点数之间距离的方法. 对于输入顺序,这种方法对称地工作是非常重要的. 目前我使用的方法是:

double distanceBetween(double a, double b) {
    return Math.abs(a - b);  // I assume that a-b = -(b-a)
}

但我不确定这是否总是对称的,或者我是否应该将代码更改为:

double distanceBetween(double a, double b) {
    if (a > b) return a - b;
    else return b - a;
}

所以我的问题是,

Math.abs(a - b) == Math.abs(b - a)

保证对a和b的所有值始终为真? 或者,有没有可能在某些情况下(由于使用了浮点数学)结果不是exactly相同?

推荐答案

计算两个浮点数之间的距离是否对称?

在Java的本机浮点运算中为是,在使用非对称舍入方法的其他语言中为否,在Java的BigDecimal中使用非对称舍入方法时可能为否(见完).

IEEE 754-2019 5.1规定:

…除非另有说明,否则执行本标准规定的返回数值结果的每一次计算操作时,应将其视为首先生成一个精确到无限精度且范围无界的中间结果,然后在必要时对该中间结果进行四舍五入以适应目的地的格式(见4和7)…

减法和绝对值是标准指定的返回数值结果的运算,没有针对它们的"另行指定"语句.−754浮点格式关于符号是对称的;对于任何可表示的数字x,IEEEx也是可表示的.因此,对于任何对称舍入方法,如果将ab舍入为某个数字x,则将ba舍入为−x.

IEEE 754规定了非对称舍入模式,例如向无穷大舍入(向上舍入).对于非对称舍入模式,ab不会总是对称地舍入到ba.例如,对于假设的两位小数浮点数,14 - 1.7将生成13(14−1.7=12.3,向上舍入为13),但1.7−14将生成−12(1.7−14=−12.3,向上舍入为−12).

然而,Java不对其本机浮点运算使用非对称舍入模式(The Java Virtual Machine Specification, Java SE 18 Edition, 2022-02-23, section 2.8, page 20).

取绝对值永远不会舍入,因为它的数学结果总是可以表示的,所以它不是分析中的一个因素.

Java BigDecimal对非对称舍入方法有一些支持,但我不清楚这些方法是内置在运算中(i.e.,将在减法过程中自动执行),还是必须手动apply.如果前者是CAE,则abba不总是在BigDecimal中生成对称结果.

Java相关问答推荐

Java中不同包中的类之间的配置共享

Java Stream,需要更新列表对象列表

多个Java线程和TreeMap.put()的非预期行为

Java中是否有某种类型的池可以避免重复最近的算术运算?

Hibernate 6支持Joda DateTime吗?

调用引发泛型异常的泛型方法时出现编译错误

JavaFX如何在MeshView中修复多个立方体?

通过移动一个类解决了潜在的StubbingProblem.它怎麽工作?

生成桥方法以解决具有相同擦除的冲突方法

SonarLint:只能有条件地调用方法(S)

我的Spring Boot测试显示&IlLegalStateException:无法加载某事的ApplicationContext.

Java17支持哪个MapR版本?

为什么Collectors.toList()不能保证易变性

项目react 堆中doOnComplete()和Subscribe()的第三个参数之间的差异

在Java泛型中使用通配符时,如何推断类型

Maven-Dependency-Plugin 3.6.+开始查找在依赖关系:分析目标期间找到的新的使用的未声明依赖关系

在输入端没有可行的替代方案'; Select *';

为什么当我输入变量而不是直接输入字符串时,我的方法不起作用?

将在 Docker 中运行的 Spring Boot 连接到在 Docker 中运行的 PostgreSQL,无需 compose 文件?

如何解释泛型类层次 struct 中子类的返回值类型和参数定义?