Java 双重比较 epsilon

标签 java floating-point currency

我编写了一个类,用 Java 中的两个 double 来测试相等、小于和大于。我的一般情况是比较可以精确到半美分的价格。 59.005 与 59.395 相比。我为这些情况选择的 epsilon 是否足够?

private final static double EPSILON = 0.00001;


/**
 * Returns true if two doubles are considered equal.  Tests if the absolute
 * difference between two doubles has a difference less then .00001.   This
 * should be fine when comparing prices, because prices have a precision of
 * .001.
 *
 * @param a double to compare.
 * @param b double to compare.
 * @return true true if two doubles are considered equal.
 */
public static boolean equals(double a, double b){
    return a == b ? true : Math.abs(a - b) < EPSILON;
}


/**
 * Returns true if two doubles are considered equal. Tests if the absolute
 * difference between the two doubles has a difference less then a given
 * double (epsilon). Determining the given epsilon is highly dependant on the
 * precision of the doubles that are being compared.
 *
 * @param a double to compare.
 * @param b double to compare
 * @param epsilon double which is compared to the absolute difference of two
 * doubles to determine if they are equal.
 * @return true if a is considered equal to b.
 */
public static boolean equals(double a, double b, double epsilon){
    return a == b ? true : Math.abs(a - b) < epsilon;
}


/**
 * Returns true if the first double is considered greater than the second
 * double.  Test if the difference of first minus second is greater then
 * .00001.  This should be fine when comparing prices, because prices have a
 * precision of .001.
 *
 * @param a first double
 * @param b second double
 * @return true if the first double is considered greater than the second
 *              double
 */
public static boolean greaterThan(double a, double b){
    return greaterThan(a, b, EPSILON);
}


/**
 * Returns true if the first double is considered greater than the second
 * double.  Test if the difference of first minus second is greater then
 * a given double (epsilon).  Determining the given epsilon is highly
 * dependant on the precision of the doubles that are being compared.
 *
 * @param a first double
 * @param b second double
 * @return true if the first double is considered greater than the second
 *              double
 */
public static boolean greaterThan(double a, double b, double epsilon){
    return a - b > epsilon;
}


/**
 * Returns true if the first double is considered less than the second
 * double.  Test if the difference of second minus first is greater then
 * .00001.  This should be fine when comparing prices, because prices have a
 * precision of .001.
 *
 * @param a first double
 * @param b second double
 * @return true if the first double is considered less than the second
 *              double
 */
public static boolean lessThan(double a, double b){
    return lessThan(a, b, EPSILON);
}


/**
 * Returns true if the first double is considered less than the second
 * double.  Test if the difference of second minus first is greater then
 * a given double (epsilon).  Determining the given epsilon is highly
 * dependant on the precision of the doubles that are being compared.
 *
 * @param a first double
 * @param b second double
 * @return true if the first double is considered less than the second
 *              double
 */
public static boolean lessThan(double a, double b, double epsilon){
    return b - a > epsilon;
}

最佳答案

您不使用 double 来表示金钱。永远不会。使用java.math.BigDecimal而是。

然后您可以指定如何精确地进行舍入(这有时是由金融应用程序中的法律规定的!),而不必像 epsilon 那样做愚蠢的黑客行为。

说真的,用浮点类型来表示金钱是极其不专业的。

关于Java 双重比较 epsilon,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/356807/

相关文章:

iphone - 我如何从货币名称列表中获取区域设置

swift - 如何在输出中获得百分之一而不是十分之一

javascript - 如何在 JavaScript 中使用 localeString 获取货币代码和金额之间的空格?

java - Java 中的 int.class 包含什么?为什么它甚至有效?

java - Grails、Grails RabbitMQ 插件、Java 、Spring AMQP - 多个客户端

c - 我们可以在常规寄存器中存储浮点吗?

c++ - 比较 float 和 int

java - 如何格式化 double ,使其永远不会显示科学记数法?

java - JPA 1.0 Hibernate & Derby HashMap 与 Enum 键用法

c - 如何检查 float 是否具有归一化尾数?