SLIM查询表比较中的浮点值

时间:2012-05-27 15:39:36

标签: fitnesse fitnesse-slim fit-framework

我对Fitnesse很新。我正在使用子集查询表。它工作正常,除非我必须比较一个浮点值。有什么办法可以将这些值与一定的准确度进行比较吗?

例如,当我将4.12与4.1234进行比较时,测试应该通过。但是现在,看起来它正在进行字符串比较而且失败了。无论如何我可以覆盖验证部分吗?

2 个答案:

答案 0 :(得分:1)

您可以使用波浪号字符表示“近似等于”,例如〜= 4.12

有关详细信息,请参阅http://fitnesse.org/FitNesse.UserGuide.SliM.ValueComparisons

答案 1 :(得分:0)

为了实现Double和Float值的近似比较,我已经覆盖了fixture类,如下所示:

public class ApproxColumnFixture extends ColumnFixture {

    @Override
    public void check(Parse cell, TypeAdapter a) {
        if (a.type == Double.class) {
            super.check(cell, new ApproxDoubleAdapter(a));
        } else if (a.type == Float.class) {
            super.check(cell, new ApproxFloatAdapter(a));
        } else {
            super.check(cell, a);
        }
    }
}

两个TypeAdapter类使用相对值 epsilon 和绝对值精度进行比较。从预期输入中检测精度,因此23.099的精度为0.001。他们还期望特殊值,例如NaN的“nan”和+/- Infinitive的“inf”。这是一个例子:

public class ApproxDoubleAdapter extends TypeAdapter {
    public final Double ZERO = new Double(0.0);

    private final double epsilon;
    private int precisions = -1;

    public ApproxDoubleAdapter(final TypeAdapter classDoubleAdapter, double epsilon) {
        this.target = classDoubleAdapter.target;
        this.fixture = classDoubleAdapter.fixture;
        this.field = classDoubleAdapter.field;
        this.method = classDoubleAdapter.method;
        this.type = classDoubleAdapter.type;
        this.isRegex = classDoubleAdapter.isRegex;

        this.epsilon = epsilon;
    }
    public ApproxDoubleAdapter(final TypeAdapter adapt) {
        this(adapt, 0.0001);
    }

    public Object parse(String s) throws Exception {
        if ((s == null) || s.equals("null")) {
            return null;
        }
        if (s.equals("0")) {
            return ZERO;
        }
        if (s.equals("nan")) {
            return Double.NaN;
        }
        if (s.equals("inf")) {
            return Double.POSITIVE_INFINITY;
        }
        precisions = s.indexOf(".");
        if (precisions >= 0) {
            precisions = s.length() - 1 - precisions;
        }
        return new Double( Double.parseDouble(s) );
    }

    public boolean equals(Object a, Object b) {
        if (a == null) {
            return (b == null);
        }
        if (b == null) {
            return (a == null);
        }
        if ((a.getClass() != Double.class) || (b.getClass() != Double.class)) {
            return false;
        }
        double aV = (Double) a;
        double bV = (Double) b;
        if (Double.isNaN(aV)) {
            return Double.isNaN(bV);
        }
        if (Double.isNaN(bV)) {
            return Double.isNaN(aV);
        }
        if (Double.isNaN(aV)) {
            return Double.isNaN(bV);
        }
        if (Double.isInfinite(aV)) {
            return Double.isInfinite(bV);
        }
        if (Double.isInfinite(bV)) {
            return Double.isInfinite(aV);
        }
        final double diff = Math.abs(aV - bV);
        if (diff <= Math.abs(aV + bV) * epsilon) {
            return true;
        }
        if (precisions > 0) {
            return diff <= Math.pow(10, precisions);
        } else if (aV == 0.0) {
            return diff < epsilon;
        } else {
            return false;
        }
    }
}