Re: [xml] XPath mod operator problems



"Daniel" == Daniel Veillard <veillard redhat com> writes:

    Daniel> On Fri, Jun 28, 2002 at 11:17:10AM +0200, Geert Kloosterman wrote:
    >> >>>>> "Peter" == Peter Jacobi <pj walter-graphtek com> writes:
    >> 
    >> > Justin Fletcher wrote:
    >> >> [...]
    >> >> This would appear to me to be compatible, and thus suitable for use.
    >> >> I haven't got earlier versions of the spec but I believe that the
    >> >> fmod function has been part of the standard library for some time.
    >> 
    >> > It's in Plauger [1992] "The Standard C library", so it's in the
    >> > 1990 version already.
    >> 
    >> It's also in the reference section of Kernigan and Ritchie, "The C
    >> Programming Language", 2nd Edition (1988), based on the ANSI C draft
    >> from October 31, 1988.

    Daniel>   Okay, can you build a patch for xpath.c and adding an
    Daniel> example in the regression tests ?

I'll give it a shot.

There's one other thing.  Isn't the real problem the comparison of the
floats?  Comparing floats is a tricky thing.

In `xmlXPathEqualValues' the comparison for floats is done by 
comparing the floats themselves.  In `xmlXPathEqualNodbSetFloat'
however, the float value is first converted to a string.  

Shouldn't this also be done for `xmlXPathEqualValues'?

The reason I think this would be good is the following.  Consider the
following code (similar to the current code of xmlXPathModValues):

    int main (int argc, char **argv)
    {
        double arg1, arg2, tmp, res;
        char buf1[100], buf2[100];

        arg1 = 8;
        arg2 = 3;
        tmp = arg1/arg2;

        res = arg2 * (tmp - (double)((int)tmp));

        if (res == 2.0)
           printf("This does NOT work: 8.0/3.0 == 2.0\n");

        ...

When I look with gdb the value of `res' is `1.9999999999999996'.
But when I do a printf("%f", res) the output is `2.000000'.

The boolean expression `res == 2.0' evaluates to false.

So what we could do is something like this:

   /* compare two float values */

   sprintf(buf1, "%g", res);
   sprintf(buf2, "%g", 2.0);

   if (!strcmp(buf1, buf2)) {
       printf("This DOES work (sprintf): 8.0/3.0 == 2.0\n");
   }

In this case the comparison does give the expected results.

The comparison 'fmod(arg1,arg2) == 2.0' works because fmod() does not
introduce any floating point noise, i.e. looking with gdb at the
return value fmod(arg1, arg2) of gives exactly `2'. 

Geert



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]