我写了一个类来测试相等,小于和大于Java中的两个双重.我的一般情况是比较可以具有半分精度的价格.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; }
Michael Borg.. 104
你不要用double来代表金钱.永远不会.请java.math.BigDecimal
改用.
然后你可以指定如何精确地进行舍入(有时在金融应用程序中由法律规定!)并且不必像这个epsilon那样做愚蠢的黑客攻击.
说真的,使用浮点类型来代表金钱是非常不专业的.
你不要用double来代表金钱.永远不会.请java.math.BigDecimal
改用.
然后你可以指定如何精确地进行舍入(有时在金融应用程序中由法律规定!)并且不必像这个epsilon那样做愚蠢的黑客攻击.
说真的,使用浮点类型来代表金钱是非常不专业的.
是.Java双精度将比你给出的0.00001的epsil更好.
由于存储浮点值而发生的任何舍入误差将小于0.00001.我经常使用1E-6
或0.000001在Java中使用双epsilon而没有任何问题.
在相关的说明中,我喜欢格式,epsilon = 1E-5;
因为我觉得它更具可读性(Java中的1E-5 = 1 x 10 ^ -5).读取代码时,1E-6很容易与1E-5区分,而当看到代码时,0.00001和0.000001看起来非常相似,我认为它们是相同的值.
哇哇哇哇 您是否有特定的原因使用浮点货币,或者使用任意精度的定点数字格式会更好?我不知道你要解决的具体问题是什么,但你应该考虑半分钱是否真的是你想要使用的东西,或者它只是一个使用不精确数字格式的工件.
如果你可以使用BigDecimal,那么使用它,否则:
/** *@param precision number of decimal digits */ public static boolean areEqualDouble(double a, double b, int precision) { return Math.abs(a - b) <= Math.pow(10, -precision); }
如果你正在处理钱,我建议检查Money设计模式(最初来自Martin Fowler关于企业架构设计的书).
我建议阅读此链接以获取动机:http: //wiki.moredesignpatterns.com/space/Value+Object+Motivation+v2