Search code examples
xpathieee-754

XPath 1.0 IEEE 754 - minimum number of bits?


I have to know what is the minimum number of bits (32, 64 or 128) used generally in XPath processors when converting a value into a floating point number defined in IEEE 754.

XML XPath Language (XPATH) Version 1.0

(https://www.w3.org/TR/1999/REC-xpath-19991116/)

States on section 4.4:

"The number function converts its argument to a number as follows:"

  • "a string that consists of optional whitespace followed by an optional minus sign followed by a Number followed by whitespace is converted to the IEEE 754 number that is nearest (according to the IEEE 754 round-to-nearest rule) to the mathematical value represented by the string; any other string is converted to NaN"

I have viewed the implementation of libxml2 (https://github.com/GNOME/libxml2/blob/22f1521122402bee88b58a463af58b5ab865dc3f/xpath.c#L9984):

double
xmlXPathStringEvalNumber(const xmlChar *str) {
    const xmlChar *cur = str;
    double ret;
    int ok = 0;
    int isneg = 0;
    int exponent = 0;
    int is_exponent_negative = 0;
#ifdef __GNUC__
    unsigned long tmp = 0;
    double temp;
#endif
    if (cur == NULL) return(0);
    while (IS_BLANK_CH(*cur)) cur++;
    if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
        return(xmlXPathNAN);
    }
    if (*cur == '-') {
        isneg = 1;
        cur++;
    }

#ifdef __GNUC__
    /*
     * tmp/temp is a workaround against a gcc compiler bug
     * http://veillard.com/gcc.bug
     */
    ret = 0;
    while ((*cur >= '0') && (*cur <= '9')) {
        ret = ret * 10;
        tmp = (*cur - '0');
        ok = 1;
        cur++;
        temp = (double) tmp;
        ret = ret + temp;
    }
#else
    ret = 0;
    while ((*cur >= '0') && (*cur <= '9')) {
        ret = ret * 10 + (*cur - '0');
        ok = 1;
        cur++;
    }
#endif

    if (*cur == '.') {
        int v, frac = 0, max;
        double fraction = 0;

        cur++;
        if (((*cur < '0') || (*cur > '9')) && (!ok)) {
            return(xmlXPathNAN);
        }
        while (*cur == '0') {
            frac = frac + 1;
            cur++;
        }
        max = frac + MAX_FRAC;
        while (((*cur >= '0') && (*cur <= '9')) && (frac < max)) {
            v = (*cur - '0');
            fraction = fraction * 10 + v;
            frac = frac + 1;
            cur++;
        }
        fraction /= pow(10.0, frac);
        ret = ret + fraction;
        while ((*cur >= '0') && (*cur <= '9'))
            cur++;
    }
    if ((*cur == 'e') || (*cur == 'E')) {
      cur++;
      if (*cur == '-') {
        is_exponent_negative = 1;
        cur++;
      } else if (*cur == '+') {
        cur++;
      }
      while ((*cur >= '0') && (*cur <= '9')) {
        if (exponent < 1000000)
          exponent = exponent * 10 + (*cur - '0');
        cur++;
      }
    }
    while (IS_BLANK_CH(*cur)) cur++;
    if (*cur != 0) return(xmlXPathNAN);
    if (isneg) ret = -ret;
    if (is_exponent_negative) exponent = -exponent;
    ret *= pow(10.0, (double)exponent);
    return(ret);
}

It is clear that this implementation uses a 64 bit space to store the results but there are other XPath processors (saxon for example: https://www.saxonica.com/) and there is a chance more implementation is going to appear. The software I'm currently working on needs to support every currently available and every future implementations of XPath 1.0 and some calculation depends on this specific minimum value.


Is there some kind of more specific requirement on this matter when someone developing an XPath processor?

Thank you in advance.


Solution

  • I think XPath 1.0 doubles are 64-bit floating point numbers, much like Java or C# double numbers or JavaScript numbers, basically relying on the same IEEE standard. XPath 2 or later have not changed that number type, instead the type system has been enhanced with other numeric types from the XML schema language like xs:integer, xs:decimal.