Hi Matt, The problem you’re having is because test only uses the approximate comparison (using current-test-epsilon) when the _expected_ value is inexact: http://api.call-cc.org/doc/scheme/inexact%3F
Since your expected value is a list (i.e. inexact? will result in #f given a list), test is testing using equal? which, as you noted, will likely fail for floating point values. All you’ll need to do to properly test your lists is to break the test down so that you are testing the floats one at a time. You could also set current-test-comparator to a function that will work given your requirements. This is the default current-test-comparator: (define (test-equal? expect res) (or (equal? expect res) (and (number? expect) (inexact? expect) (inexact? res) (approx-equal? expect res (current-test-epsilon))))) You could change it to something like: (define (rgb-test-equal? expect res) (or (equal? expect res) (and (rgb? expect) (rgb-equal? expect res)) (and (number? expect) (inexact? expect) (inexact? res) (approx-equal? expect res (current-test-epsilon))))) With appropriate definitions for rgb? and rgb-equal? Matt Gushee writes: > Hi, folks-- > > I am working on an application that does a lot of floating-point > calculations, and I'm having trouble with the test suite. The program > is based on the imlib2 egg, and it does some fairly simple image > processing for web applications, so the numbers in question are RGBA > color values. Internally I am handling all the numbers as floats in > the range 0-1, because the blending and compositing formulas are much > more straightforward that way compared to using integers 0-255. > > So I have a number of functions that produce lists of numbers like these: > > '(0.323 0.788834 0.12 0.4) > '(0 0 0 1.0) > '(0.6666666667 0.4 0.562 0.0) > > And given the above, a moderate degree of imprecision in the results > is perfectly acceptable - I haven't yet confirmed this with actual > images, but I'm thinking as much as 0.5% variance should work fine > (basically, as long as the colors in the generated images look as > expected to a casual observer, the result should be acceptable). So of > course I want the test results to reflect this. > > I am using the following procedure to compare number lists: > > (define (list= l1 l2) > (and (= (length l1) (length l2)) > (let loop ((l1* l1) (l2* l2)) > (cond > ((null? l1*) #t) > ((= (car l1*) (car l2*)) (loop (cdr l1*) (cdr l2*))) > (else #f))))) > > And for the tests that use this predicate, I set > > (current-test-epsilon 0.005) > > [or 0.002 or 0.001 - it doesn't seem to make any difference] > > But I'm finding that certain tests still fail unexpectedly, e.g. > > 2.03.10: (parse-color "167,215,51" #f) => '(0.655 0.843 0.200 1.0) [ FAIL] > expected (0.655 0.843 0.2 1.0) > but got (0.654901960784314 0.843137254901961 0.2 1.0) > > But: > > (/ 0.654901960784314 0.655) => 0.999850321808113 > (/ 0.843137254901961 0.843) => 1.0001628172028 > > So it would appear that the epsilon value does not apply to these tests. > > I can certainly define a custom equality predicate that will do what I > need, but this is bugging me. I guess I don't really understand how > epsilon is supposed to work. The test egg documentation says that > applies to 'inexact comparisons', but I can't find a definition of > 'inexact comparison'. I have also read that '=' may be unreliable for > inexact numbers, but I don't know what else to use. Perhaps 'fp=' from > the Chicken library? Then I would have to ensure that all numbers are > expressed as floats, whereas currently my code has a number of cases > where 1 and 0 are expressed as integers. > > So ... do I understand the problem correctly? Any recommendations? > > Matt Gushee > > _______________________________________________ > Chicken-users mailing list > Chicken-users@nongnu.org > https://lists.nongnu.org/mailman/listinfo/chicken-users -- Alex _______________________________________________ Chicken-users mailing list Chicken-users@nongnu.org https://lists.nongnu.org/mailman/listinfo/chicken-users