本文介绍了Java双比较epsilon的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个类,测试的平等,小于,并在Java中两个双打比。我的一般情况是比较可以有一个半分精度的价格。 59.005与59.395相比。是我所选择的epsilon适合那些情况?

  private final static EPSILON = 0.00001; 


/ **
*如果两个双打相等,则返回true。测试两个双打之间的绝对
*差异是否小于0.00001。这个
*在比较价格时应该没问题,因为价格的精确度是
* .001。
*
* @param双重比较。
* @param b双重比较。
* @return如果两个双打相等,则返回true。
* /
public static boolean equals(double a,double b){
return a == b? true:Math.abs(a - b) EPSILON;
}


/ **
*如果两个双打相等,则返回true。测试两个双打之间的绝对
*差异是否小于给定的
* double(epsilon)。确定给定的ε高度依赖于正在比较的双打的
*精度。
*
* @param双重比较。
* @param b double来比较
* @param epsilon double与两个
* double的绝对差值进行比较以确定它们是否相等。
* @如果a等于b,则返回true。
* /
public static boolean equals(double a,double b,double epsilon){
return a == b? true:Math.abs(a - b)小量;
}


/ **
*如果第一个double被认为大于第二个
* double,则返回true。测试第一个减去第二个的差值是否大于
* .00001。在比较价格时应该没问题,因为价格的精确度是
* .001。
*
* @param第一个双倍
* @param b第二个双倍
*返回true如果第一个double被认为大于第二个
* double
* /
public static boolean greaterThan(double a,double b){
return greaterThan(a,b,EPSILON);
}


/ **
*如果第一个double被认为大于第二个
* double,则返回true。测试第一个减去第二个的差值是否大于
* a给定的双倍(epsilon)。确定给定的epsilon高度
*取决于正在比较的双打的精度。
*
* @param第一个双倍
* @param b第二个双倍
*返回true如果第一个double被认为大于第二个
* double
* /
public static boolean greaterThan(double a,double b,double epsilon){
return a - b>小量;


$ b / **
*如果第一个double被认为小于第二个
* double,则返回true。测试第二个减去第一个的差值是否大于
* .00001。在比较价格时应该没问题,因为价格的精确度是
* .001。
*
* @param第一个双重
* @param b第二个双倍
* @return如果第一个double被认为小于第二个
* double
* /
public static boolean lessThan(double a,double b){
return lessThan(a,b,EPSILON);


$ b / **
*如果第一个double小于第二个
* double,则返回true。测试第二个减去第一个的差值是否大于
* a给定的双倍(epsilon)。确定给定的epsilon高度
*取决于正在比较的双打的精度。
*
* @param第一个双重
* @param b第二个双倍
* @return如果第一个double被认为小于第二个
* double
* /
public static boolean lessThan(double a,double b,double epsilon){
return b - a>小量;


解决方案

代表金钱。永远不会。使用 java.math.BigDecimal



然后您可以指定如何精确舍入(有时在财务应用程序中由法律规定!没有必要像这个epsilon的东西愚蠢的黑客。



严重的是,使用浮点类型来表示钱是非常不专业。

I wrote a class that tests for equality, less than, and greater than with two doubles in Java. My general case is comparing price that can have an accuracy of a half cent. 59.005 compared to 59.395. Is the epsilon I chose adequate for those cases?

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;
}
解决方案

You do NOT use double to represent money. Not ever. Use java.math.BigDecimal instead.

Then you can specify how exactly to do rounding (which is sometimes dictated by law in financial applications!) and don't have to do stupid hacks like this epsilon thing.

Seriously, using floating point types to represent money is extremely unprofessional.

这篇关于Java双比较epsilon的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 08:38