[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Re: [xml] XPath fix
- From: Daniel Veillard <veillard redhat com>
- To: Cyberthymia <cyberthymia yahoo co uk>
- Cc: xml gnome org
- Subject: Re: [xml] XPath fix
- Date: Fri, 22 Mar 2002 08:40:41 -0500
On Fri, Mar 22, 2002 at 12:23:39PM -0000, Cyberthymia wrote:
> > Section 3.5 of the XPath spec states:
> > "This is the same as the % operator in Java and ECMAScript."
> > "This is not the same as the IEEE 754 remainder operation,
> > which returns the remainder from a rounding division."
> >
> > So they may be right, I hate those parts where XPath/XSLT relies on Java
> >for the semantic of operations, it is usually a mess.
>
> That bit confused the heck out of me - so does that imply that Java doesn't
> do IEEE 754 floating point numbers properly?
seems to imply it, yes. You're surprized ?
> I've found another couple of problems with float, round and ceil.
> floor(-5.2) returns -5 instead of -6
> ceiling(-5.2) returns -4 instead of -5
> round(-5.6) returns -5 instead of -6
> I've had a look at the code in xpath.c that does this maths
> (xmlXPathFloorFunction(), etc) and what I thought would have been the
> correct fix (by using the real C functions) in all 3 cases has been "#if
> 0"'d out and replaced by approximations doing wierd things with casts.
> This is probably a silly question, but was there a specific issue caused by
> using the C functions that stopped them from working?
Looked at it, I wonder if I didn't do this to avoid using the
functions from the math library when avoidable. Weird casts are
a sign of ownership ... it seems I forgot about negative values though :-)
Apparently I got burned by a problem with floor() as a comment
indicates : "floor(0.999999999999) => 1.0 !!!!!!!!!!!"
and decided to bypass it using direct cast to implement the right
semantic.
The enclosed patch tries to fix this, could you build a test file
like the others in test/XPath/expr/ testings those 3 functions and
raise errors if there is still some to fix,
thanks,
Daniel
--
Daniel Veillard | Red Hat Network https://rhn.redhat.com/
veillard redhat com | libxml GNOME XML XSLT toolkit http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine http://rpmfind.net/
Index: xpath.c
===================================================================
RCS file: /cvs/gnome/gnome-xml/xpath.c,v
retrieving revision 1.173
diff -c -r1.173 xpath.c
*** xpath.c 22 Mar 2002 12:23:14 -0000 1.173
--- xpath.c 22 Mar 2002 13:39:34 -0000
***************
*** 6483,6497 ****
*/
void
xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
CHECK_ARITY(1);
CAST_TO_NUMBER;
CHECK_TYPE(XPATH_NUMBER);
! #if 0
! ctxt->value->floatval = floor(ctxt->value->floatval);
! #else
! /* floor(0.999999999999) => 1.0 !!!!!!!!!!! */
! ctxt->value->floatval = (double)((int) ctxt->value->floatval);
! #endif
}
/**
--- 6483,6501 ----
*/
void
xmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
+ double f;
+
CHECK_ARITY(1);
CAST_TO_NUMBER;
CHECK_TYPE(XPATH_NUMBER);
!
! f = (double)((int) ctxt->value->floatval);
! if (f != ctxt->value->floatval) {
! if (ctxt->value->floatval > 0)
! ctxt->value->floatval = f;
! else
! ctxt->value->floatval = f - 1;
! }
}
/**
***************
*** 6516,6523 ****
ctxt->value->floatval = ceil(ctxt->value->floatval);
#else
f = (double)((int) ctxt->value->floatval);
! if (f != ctxt->value->floatval)
! ctxt->value->floatval = f + 1;
#endif
}
--- 6520,6531 ----
ctxt->value->floatval = ceil(ctxt->value->floatval);
#else
f = (double)((int) ctxt->value->floatval);
! if (f != ctxt->value->floatval) {
! if (ctxt->value->floatval > 0)
! ctxt->value->floatval = f + 1;
! else
! ctxt->value->floatval = f;
! }
#endif
}
***************
*** 6546,6560 ****
(ctxt->value->floatval == 0.0))
return;
- #if 0
- f = floor(ctxt->value->floatval);
- #else
f = (double)((int) ctxt->value->floatval);
! #endif
! if (ctxt->value->floatval < f + 0.5)
! ctxt->value->floatval = f;
! else
! ctxt->value->floatval = f + 1;
}
/************************************************************************
--- 6554,6571 ----
(ctxt->value->floatval == 0.0))
return;
f = (double)((int) ctxt->value->floatval);
! if (ctxt->value->floatval < 0) {
! if (ctxt->value->floatval < f - 0.5)
! ctxt->value->floatval = f - 1;
! else
! ctxt->value->floatval = f;
! } else {
! if (ctxt->value->floatval < f + 0.5)
! ctxt->value->floatval = f;
! else
! ctxt->value->floatval = f + 1;
! }
}
/************************************************************************
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]