mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-03-31 06:50:06 +03:00
more patches from Richard Jinks Updated tests though they show a
* trionan.c trionan.h xpath.c: more patches from Richard Jinks * test/XPath/expr/compare test/XPath/expr/equality test/XPath/expr/floats test/XPath/expr/functions test/XPath/expr/strings result/XPath/expr/compare result/XPath/expr/equality result/XPath/expr/floats result/XPath/expr/functions result/XPath/expr/strings: Updated tests though they show a divergence on Linux Daniel
This commit is contained in:
parent
28dfed14a2
commit
21458c85e2
10
ChangeLog
10
ChangeLog
@ -1,3 +1,13 @@
|
||||
Wed Mar 27 17:09:43 CET 2002 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* trionan.c trionan.h xpath.c: more patches from Richard Jinks
|
||||
* test/XPath/expr/compare test/XPath/expr/equality
|
||||
test/XPath/expr/floats test/XPath/expr/functions
|
||||
test/XPath/expr/strings result/XPath/expr/compare
|
||||
result/XPath/expr/equality result/XPath/expr/floats
|
||||
result/XPath/expr/functions result/XPath/expr/strings: Updated
|
||||
tests though they show a divergence on Linux
|
||||
|
||||
Wed Mar 27 10:06:53 CET 2002 Daniel Veillard <daniel@veillard.com>
|
||||
|
||||
* xpath.c trionan.c: previous commit also included patches
|
||||
|
@ -1,4 +1,20 @@
|
||||
|
||||
========================
|
||||
Expression: 0<0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 0<=0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 0>0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 0>=0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 0<1
|
||||
Object is a Boolean : true
|
||||
@ -79,6 +95,22 @@ Object is a Boolean : false
|
||||
Expression: 0>='1.2'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 0<'-0.2'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 0<='-0.2'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 0>'-0.2'
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 0>='-0.2'
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: false()<1
|
||||
Object is a Boolean : true
|
||||
@ -94,3 +126,59 @@ Object is a Boolean : false
|
||||
========================
|
||||
Expression: 0>=true()
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' > 'a'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' > 'b'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'b' > 'a'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' < 'a'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' < 'b'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'b' < 'a'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' >= 'a'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' >= 'b'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'b' >= 'a'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' <= 'a'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' <= 'b'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'b' <= 'a'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' > '0.0'
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a' < '0.0'
|
||||
Object is a Boolean : false
|
||||
|
@ -94,3 +94,11 @@ Object is a Boolean : false
|
||||
========================
|
||||
Expression: 'test'!=false()
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 'a'=0.0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 'a'!=0.0
|
||||
Object is a Boolean : true
|
||||
|
@ -25,7 +25,7 @@ Object is a number : 0.00123
|
||||
|
||||
========================
|
||||
Expression: 1 div 0
|
||||
Object is a number : +Infinity
|
||||
Object is a number : Infinity
|
||||
|
||||
========================
|
||||
Expression: -1 div 0
|
||||
@ -35,6 +35,10 @@ Object is a number : -Infinity
|
||||
Expression: 0 div 0
|
||||
Object is a number : NaN
|
||||
|
||||
========================
|
||||
Expression: 1 div -0
|
||||
Object is a number : -Infinity
|
||||
|
||||
========================
|
||||
Expression: (1 div 0) > 0
|
||||
Object is a Boolean : true
|
||||
@ -58,3 +62,135 @@ Object is a Boolean : false
|
||||
========================
|
||||
Expression: (0 div 0) < 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: (1 div -0) > 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: (1 div -0) < 0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 0 div 0 = 0 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 0 div 0 != 0 div 0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 0 div 0 > 0 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 0 div 0 < 0 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 0 div 0 >= 0 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 0 div 0 <= 0 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 = -1 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 != -1 div 0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 > -1 div 0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 < -1 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 >= -1 div 0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 <= -1 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 = 1 div 0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 != 1 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 > 1 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 < 1 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 >= -1 div 0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 1 div 0 <= -1 div 0
|
||||
Object is a Boolean : false
|
||||
|
||||
========================
|
||||
Expression: -2 div 0 = -1 div 0
|
||||
Object is a Boolean : true
|
||||
|
||||
========================
|
||||
Expression: 1 div floor(0.1)
|
||||
Object is a number : Infinity
|
||||
|
||||
========================
|
||||
Expression: 1 div floor(-0.1)
|
||||
Object is a number : -1
|
||||
|
||||
========================
|
||||
Expression: 1 div floor(-0)
|
||||
Object is a number : -Infinity
|
||||
|
||||
========================
|
||||
Expression: 1 div floor(0)
|
||||
Object is a number : Infinity
|
||||
|
||||
========================
|
||||
Expression: 1 div ceiling(0.1)
|
||||
Object is a number : 1
|
||||
|
||||
========================
|
||||
Expression: 1 div ceiling(-0.1)
|
||||
Object is a number : -Infinity
|
||||
|
||||
========================
|
||||
Expression: 1 div ceiling(-0)
|
||||
Object is a number : -Infinity
|
||||
|
||||
========================
|
||||
Expression: 1 div ceiling(0)
|
||||
Object is a number : Infinity
|
||||
|
||||
========================
|
||||
Expression: 1 div round(0.1)
|
||||
Object is a number : Infinity
|
||||
|
||||
========================
|
||||
Expression: 1 div round(-0.1)
|
||||
Object is a number : -Infinity
|
||||
|
||||
========================
|
||||
Expression: 1 div round(-0)
|
||||
Object is a number : -Infinity
|
||||
|
||||
========================
|
||||
Expression: 1 div round(0)
|
||||
Object is a number : Infinity
|
||||
|
@ -12,9 +12,85 @@ Expression: number("1.5")
|
||||
Object is a number : 1.5
|
||||
|
||||
========================
|
||||
Expression: concat("titi",'toto')
|
||||
Object is a string : tititoto
|
||||
Expression: number('abc')
|
||||
Object is a number : NaN
|
||||
|
||||
========================
|
||||
Expression: concat("titi",'toto',"tata","last")
|
||||
Object is a string : tititototatalast
|
||||
Expression: floor(0.1)
|
||||
Object is a number : 0
|
||||
|
||||
========================
|
||||
Expression: floor(-0.1)
|
||||
Object is a number : -1
|
||||
|
||||
========================
|
||||
Expression: floor(-0)
|
||||
Object is a number : 0
|
||||
|
||||
========================
|
||||
Expression: floor(0)
|
||||
Object is a number : 0
|
||||
|
||||
========================
|
||||
Expression: floor(5.2)
|
||||
Object is a number : 5
|
||||
|
||||
========================
|
||||
Expression: floor(-5.2)
|
||||
Object is a number : -6
|
||||
|
||||
========================
|
||||
Expression: ceiling(0.1)
|
||||
Object is a number : 1
|
||||
|
||||
========================
|
||||
Expression: ceiling(-0.1)
|
||||
Object is a number : 0
|
||||
|
||||
========================
|
||||
Expression: ceiling(-0)
|
||||
Object is a number : 0
|
||||
|
||||
========================
|
||||
Expression: ceiling(0)
|
||||
Object is a number : 0
|
||||
|
||||
========================
|
||||
Expression: ceiling(5.2)
|
||||
Object is a number : 6
|
||||
|
||||
========================
|
||||
Expression: ceiling(-5.2)
|
||||
Object is a number : -5
|
||||
|
||||
========================
|
||||
Expression: round(0.1)
|
||||
Object is a number : 0
|
||||
|
||||
========================
|
||||
Expression: round(5.2)
|
||||
Object is a number : 5
|
||||
|
||||
========================
|
||||
Expression: round(5.5)
|
||||
Object is a number : 6
|
||||
|
||||
========================
|
||||
Expression: round(5.6)
|
||||
Object is a number : 6
|
||||
|
||||
========================
|
||||
Expression: round(-0.1)
|
||||
Object is a number : 0
|
||||
|
||||
========================
|
||||
Expression: round(-5.2)
|
||||
Object is a number : -5
|
||||
|
||||
========================
|
||||
Expression: round(-5.5)
|
||||
Object is a number : -5
|
||||
|
||||
========================
|
||||
Expression: round(-5.6)
|
||||
Object is a number : -6
|
||||
|
@ -27,6 +27,14 @@ Object is a string : tititoto
|
||||
Expression: concat("titi","toto","tata")
|
||||
Object is a string : tititototata
|
||||
|
||||
========================
|
||||
Expression: concat("titi",'toto')
|
||||
Object is a string : tititoto
|
||||
|
||||
========================
|
||||
Expression: concat("titi",'toto',"tata","last")
|
||||
Object is a string : tititototatalast
|
||||
|
||||
========================
|
||||
Expression: starts-with("tititoto","titi")
|
||||
Object is a Boolean : true
|
||||
|
@ -1,3 +1,7 @@
|
||||
0<0
|
||||
0<=0
|
||||
0>0
|
||||
0>=0
|
||||
0<1
|
||||
0<=1
|
||||
0>1
|
||||
@ -18,7 +22,25 @@
|
||||
0<='1.2'
|
||||
0>'1.2'
|
||||
0>='1.2'
|
||||
0<'-0.2'
|
||||
0<='-0.2'
|
||||
0>'-0.2'
|
||||
0>='-0.2'
|
||||
false()<1
|
||||
false()<=1
|
||||
0>true()
|
||||
0>=true()
|
||||
'a' > 'a'
|
||||
'a' > 'b'
|
||||
'b' > 'a'
|
||||
'a' < 'a'
|
||||
'a' < 'b'
|
||||
'b' < 'a'
|
||||
'a' >= 'a'
|
||||
'a' >= 'b'
|
||||
'b' >= 'a'
|
||||
'a' <= 'a'
|
||||
'a' <= 'b'
|
||||
'b' <= 'a'
|
||||
'a' > '0.0'
|
||||
'a' < '0.0'
|
||||
|
@ -22,4 +22,5 @@ true()='test'
|
||||
false()='test'
|
||||
'test'!=true()
|
||||
'test'!=false()
|
||||
|
||||
'a'=0.0
|
||||
'a'!=0.0
|
||||
|
@ -7,9 +7,43 @@
|
||||
1 div 0
|
||||
-1 div 0
|
||||
0 div 0
|
||||
1 div -0
|
||||
(1 div 0) > 0
|
||||
(1 div 0) < 0
|
||||
(-1 div 0) > 0
|
||||
(-1 div 0) < 0
|
||||
(0 div 0) > 0
|
||||
(0 div 0) < 0
|
||||
(1 div -0) > 0
|
||||
(1 div -0) < 0
|
||||
0 div 0 = 0 div 0
|
||||
0 div 0 != 0 div 0
|
||||
0 div 0 > 0 div 0
|
||||
0 div 0 < 0 div 0
|
||||
0 div 0 >= 0 div 0
|
||||
0 div 0 <= 0 div 0
|
||||
1 div 0 = -1 div 0
|
||||
1 div 0 != -1 div 0
|
||||
1 div 0 > -1 div 0
|
||||
1 div 0 < -1 div 0
|
||||
1 div 0 >= -1 div 0
|
||||
1 div 0 <= -1 div 0
|
||||
1 div 0 = 1 div 0
|
||||
1 div 0 != 1 div 0
|
||||
1 div 0 > 1 div 0
|
||||
1 div 0 < 1 div 0
|
||||
1 div 0 >= -1 div 0
|
||||
1 div 0 <= -1 div 0
|
||||
-2 div 0 = -1 div 0
|
||||
1 div floor(0.1)
|
||||
1 div floor(-0.1)
|
||||
1 div floor(-0)
|
||||
1 div floor(0)
|
||||
1 div ceiling(0.1)
|
||||
1 div ceiling(-0.1)
|
||||
1 div ceiling(-0)
|
||||
1 div ceiling(0)
|
||||
1 div round(0.1)
|
||||
1 div round(-0.1)
|
||||
1 div round(-0)
|
||||
1 div round(0)
|
||||
|
@ -1,5 +1,24 @@
|
||||
true()
|
||||
false()
|
||||
number("1.5")
|
||||
concat("titi",'toto')
|
||||
concat("titi",'toto',"tata","last")
|
||||
number('abc')
|
||||
floor(0.1)
|
||||
floor(-0.1)
|
||||
floor(-0)
|
||||
floor(0)
|
||||
floor(5.2)
|
||||
floor(-5.2)
|
||||
ceiling(0.1)
|
||||
ceiling(-0.1)
|
||||
ceiling(-0)
|
||||
ceiling(0)
|
||||
ceiling(5.2)
|
||||
ceiling(-5.2)
|
||||
round(0.1)
|
||||
round(5.2)
|
||||
round(5.5)
|
||||
round(5.6)
|
||||
round(-0.1)
|
||||
round(-5.2)
|
||||
round(-5.5)
|
||||
round(-5.6)
|
||||
|
@ -5,6 +5,8 @@ string(true())
|
||||
string(false())
|
||||
concat("titi","toto")
|
||||
concat("titi","toto","tata")
|
||||
concat("titi",'toto')
|
||||
concat("titi",'toto',"tata","last")
|
||||
starts-with("tititoto","titi")
|
||||
starts-with("tititoto","to")
|
||||
contains("tititototata","titi")
|
||||
|
300
trionan.c
300
trionan.c
@ -93,6 +93,9 @@ static const char rcsid[] = "@(#)$Id$";
|
||||
* Definitions
|
||||
*/
|
||||
|
||||
#define TRIO_TRUE (1 == 1)
|
||||
#define TRIO_FALSE (0 == 1)
|
||||
|
||||
/* We must enable IEEE floating-point on Alpha */
|
||||
#if defined(__alpha) && !defined(_IEEE_FP)
|
||||
# if defined(TRIO_COMPILER_DECC)
|
||||
@ -145,11 +148,6 @@ static const char rcsid[] = "@(#)$Id$";
|
||||
|
||||
static TRIO_CONST double internalEndianMagic = 7.949928895127363e-275;
|
||||
|
||||
/* Mask for the sign */
|
||||
static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Mask for the exponent */
|
||||
static TRIO_CONST unsigned char ieee_754_exponent_mask[] = {
|
||||
0x7F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
@ -160,6 +158,11 @@ static TRIO_CONST unsigned char ieee_754_mantissa_mask[] = {
|
||||
0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
/* Mask for the sign bit */
|
||||
static TRIO_CONST unsigned char ieee_754_sign_mask[] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
/* Bit-pattern for negative zero */
|
||||
static TRIO_CONST unsigned char ieee_754_negzero_array[] = {
|
||||
0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
@ -196,7 +199,7 @@ trio_make_double(TRIO_CONST unsigned char *values)
|
||||
}
|
||||
|
||||
/*
|
||||
* trio_examine_double
|
||||
* trio_is_special_quantity
|
||||
*/
|
||||
TRIO_PRIVATE int
|
||||
trio_is_special_quantity(double number,
|
||||
@ -204,7 +207,7 @@ trio_is_special_quantity(double number,
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char current;
|
||||
int is_special_quantity = (1 == 1);
|
||||
int is_special_quantity = TRIO_TRUE;
|
||||
|
||||
*has_mantissa = 0;
|
||||
|
||||
@ -217,33 +220,24 @@ trio_is_special_quantity(double number,
|
||||
return is_special_quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
Get the sign value
|
||||
|
||||
@return 1 for negative, 0 for positive
|
||||
*/
|
||||
TRIO_PUBLIC int
|
||||
trio_get_sign(double number)
|
||||
/*
|
||||
* trio_is_negative
|
||||
*/
|
||||
TRIO_PRIVATE int
|
||||
trio_is_negative(double number)
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned char current;
|
||||
int sign = (1 == 1);
|
||||
int is_negative = TRIO_FALSE;
|
||||
|
||||
for (i = 0; i < (unsigned int)sizeof(double); i++) {
|
||||
current = ((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)];
|
||||
sign
|
||||
&= ((current & ieee_754_sign_mask[i]) == ieee_754_sign_mask[i]);
|
||||
is_negative |= (((unsigned char *)&number)[TRIO_DOUBLE_INDEX(i)]
|
||||
& ieee_754_sign_mask[i]);
|
||||
}
|
||||
return sign;
|
||||
return is_negative;
|
||||
}
|
||||
|
||||
/**
|
||||
Generate negative zero
|
||||
|
||||
@return Floating-point representation of negative zero.
|
||||
*/
|
||||
TRIO_PUBLIC double
|
||||
trio_nzero(void)
|
||||
trio_nzero(void)
|
||||
{
|
||||
return trio_make_double(ieee_754_negzero_array);
|
||||
}
|
||||
@ -383,7 +377,7 @@ trio_isnan(TRIO_VOLATILE double number)
|
||||
|
||||
#elif defined(TRIO_COMPILER_MSVC)
|
||||
/*
|
||||
* MSC has an _isnan() function
|
||||
* MSVC has an _isnan() function
|
||||
*/
|
||||
return _isnan(number);
|
||||
|
||||
@ -501,6 +495,221 @@ trio_isinf(TRIO_VOLATILE double number)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Check for finity.
|
||||
|
||||
@param number An arbitrary floating-point number.
|
||||
@return Boolean value indicating whether or not the number is a finite.
|
||||
*/
|
||||
TRIO_PUBLIC int
|
||||
trio_isfinite(TRIO_VOLATILE double number)
|
||||
{
|
||||
#if defined(isfinite)
|
||||
/*
|
||||
* C99 defines isfinite() as a macro.
|
||||
*/
|
||||
return isfinite(number);
|
||||
|
||||
#elif defined(TRIO_COMPILER_MSVC)
|
||||
/*
|
||||
* MSVC uses _finite().
|
||||
*/
|
||||
return _finite(number);
|
||||
|
||||
#elif defined(USE_IEEE_754)
|
||||
/*
|
||||
* Examine IEEE 754 bit-pattern. For finity we do not care about the
|
||||
* mantissa.
|
||||
*/
|
||||
int dummy;
|
||||
|
||||
return (! trio_is_special_quantity(number, &dummy));
|
||||
|
||||
#else
|
||||
/*
|
||||
* Fallback solution.
|
||||
*/
|
||||
return ((trio_isinf(number) == 0) && (trio_isnan(number) == 0));
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* The sign of NaN is always false
|
||||
*/
|
||||
TRIO_PRIVATE int
|
||||
trio_fpclass(TRIO_VOLATILE double number,
|
||||
int *is_negative)
|
||||
{
|
||||
#if defined(fpclassify) && defined(signbit)
|
||||
/*
|
||||
* C99 defines fpclassify() and signbit() as a macros
|
||||
*/
|
||||
*is_negative = signbit(number);
|
||||
switch (fpclassify(number)) {
|
||||
case FP_NAN:
|
||||
return TRIO_FP_NAN;
|
||||
case FP_INFINITE:
|
||||
return TRIO_FP_INFINITE;
|
||||
case FP_SUBNORMAL:
|
||||
return TRIO_FP_SUBNORMAL;
|
||||
case FP_ZERO:
|
||||
return TRIO_FP_ZERO;
|
||||
default:
|
||||
return TRIO_FP_NORMAL;
|
||||
}
|
||||
|
||||
#elif defined(TRIO_COMPILER_DECC)
|
||||
/*
|
||||
* DECC has an fp_class() function.
|
||||
*/
|
||||
switch (fp_class(number)) {
|
||||
case FP_QNAN:
|
||||
case FP_SNAN:
|
||||
*is_negative = TRIO_FALSE; /* NaN has no sign */
|
||||
return TRIO_FP_NAN;
|
||||
case FP_POS_INF:
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_INFINITE;
|
||||
case FP_NEG_INF:
|
||||
*is_negative = TRIO_TRUE;
|
||||
return TRIO_FP_INFINITE;
|
||||
case FP_POS_DENORM:
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_SUBNORMAL;
|
||||
case FP_NEG_DENORM:
|
||||
*is_negative = TRIO_TRUE;
|
||||
return TRIO_FP_SUBNORMAL;
|
||||
case FP_POS_ZERO:
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_ZERO;
|
||||
case FP_NEG_ZERO:
|
||||
*is_negative = TRIO_TRUE;
|
||||
return TRIO_FP_ZERO;
|
||||
case FP_POS_NORM:
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_NORMAL;
|
||||
case FP_NEG_NORM:
|
||||
*is_negative = TRIO_TRUE;
|
||||
return TRIO_FP_NORMAL;
|
||||
default:
|
||||
/* Just in case... */
|
||||
*is_negative = (number < 0.0);
|
||||
return TRIO_FP_NORMAL;
|
||||
}
|
||||
|
||||
#elif defined(TRIO_COMPILER_MSVC)
|
||||
/*
|
||||
* MSVC has an _fpclass() function.
|
||||
*/
|
||||
switch (_fpclass(number)) {
|
||||
case _FPCLASS_QNAN:
|
||||
case _FPCLASS_SNAN:
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_NAN;
|
||||
case _FPCLASS_PINF:
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_INFINITE;
|
||||
case _FPCLASS_NINF:
|
||||
*is_negative = TRIO_TRUE;
|
||||
return TRIO_FP_INFINITE;
|
||||
case _FPCLASS_PD:
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_SUBNORMAL;
|
||||
case _FPCLASS_ND:
|
||||
*is_negative = TRIO_TRUE;
|
||||
return TRIO_FP_SUBNORMAL;
|
||||
case _FPCLASS_PZ:
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_ZERO;
|
||||
case _FPCLASS_NZ:
|
||||
*is_negative = TRIO_TRUE;
|
||||
return TRIO_FP_ZERO;
|
||||
case _FPCLASS_PN:
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_NORMAL;
|
||||
case _FPCLASS_NN:
|
||||
*is_negative = TRIO_TRUE;
|
||||
return TRIO_FP_NORMAL;
|
||||
default:
|
||||
/* Just in case... */
|
||||
*is_negative = (number < 0.0);
|
||||
return TRIO_FP_NORMAL;
|
||||
}
|
||||
|
||||
#else
|
||||
/*
|
||||
* Fallback solution.
|
||||
*/
|
||||
int rc;
|
||||
|
||||
if (number == 0.0) {
|
||||
/*
|
||||
* In IEEE 754 the sign of zero is ignored in comparisons, so we
|
||||
* have to handle this as a special case by examining the sign bit
|
||||
* directly.
|
||||
*/
|
||||
#if defined(USE_IEEE_754)
|
||||
*is_negative = trio_is_negative(number);
|
||||
#else
|
||||
*is_negative = TRIO_FALSE; /* FIXME */
|
||||
#endif
|
||||
return TRIO_FP_ZERO;
|
||||
}
|
||||
if (trio_isnan(number)) {
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_NAN;
|
||||
}
|
||||
if ((rc = trio_isinf(number))) {
|
||||
*is_negative = (rc == -1);
|
||||
return TRIO_FP_INFINITE;
|
||||
}
|
||||
if ((number > 0.0) && (number < DBL_MIN)) {
|
||||
*is_negative = TRIO_FALSE;
|
||||
return TRIO_FP_SUBNORMAL;
|
||||
}
|
||||
if ((number < 0.0) && (number > -DBL_MIN)) {
|
||||
*is_negative = TRIO_TRUE;
|
||||
return TRIO_FP_SUBNORMAL;
|
||||
}
|
||||
*is_negative = (number < 0.0);
|
||||
return TRIO_FP_NORMAL;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
Examine the sign of a number.
|
||||
|
||||
@param number An arbitrary floating-point number.
|
||||
@return Boolean value indicating whether or not the number has the
|
||||
sign bit set (i.e. is negative).
|
||||
*/
|
||||
TRIO_PUBLIC int
|
||||
trio_signbit(TRIO_VOLATILE double number)
|
||||
{
|
||||
int is_negative;
|
||||
|
||||
(void)trio_fpclass(number, &is_negative);
|
||||
return is_negative;
|
||||
}
|
||||
|
||||
/**
|
||||
Examine the class of a number.
|
||||
|
||||
@param number An arbitrary floating-point number.
|
||||
@return Enumerable value indicating the class of @p number
|
||||
*/
|
||||
TRIO_PUBLIC int
|
||||
trio_fpclassify(TRIO_VOLATILE double number)
|
||||
{
|
||||
int dummy;
|
||||
|
||||
return trio_fpclass(number, &dummy);
|
||||
}
|
||||
|
||||
|
||||
/** @} SpecialQuantities */
|
||||
|
||||
/*************************************************************************
|
||||
@ -514,6 +723,33 @@ trio_isinf(TRIO_VOLATILE double number)
|
||||
#if defined(STANDALONE)
|
||||
# include <stdio.h>
|
||||
|
||||
static const char *getClassification(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case TRIO_FP_INFINITE:
|
||||
return "FP_INFINITE";
|
||||
case TRIO_FP_NAN:
|
||||
return "FP_NAN";
|
||||
case TRIO_FP_NORMAL:
|
||||
return "FP_NORMAL";
|
||||
case TRIO_FP_SUBNORMAL:
|
||||
return "FP_SUBNORMAL";
|
||||
case TRIO_FP_ZERO:
|
||||
return "FP_ZERO";
|
||||
default:
|
||||
return "FP_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
static void print_class(const char *prefix, double number)
|
||||
{
|
||||
printf("%-6s: %s %-15s %g\n",
|
||||
prefix,
|
||||
trio_signbit(number) ? "-" : "+",
|
||||
getClassification(trio_fpclassify(number)),
|
||||
number);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
double my_nan;
|
||||
@ -527,6 +763,16 @@ int main(void)
|
||||
my_pinf = trio_pinf();
|
||||
my_ninf = trio_ninf();
|
||||
|
||||
print_class("Nan", my_nan);
|
||||
print_class("PInf", my_pinf);
|
||||
print_class("NInf", my_ninf);
|
||||
print_class("PZero", 0.0);
|
||||
print_class("NZero", -0.0);
|
||||
print_class("PNorm", 1.0);
|
||||
print_class("NNorm", -1.0);
|
||||
print_class("PSub", 1.01e-307 - 1.00e-307);
|
||||
print_class("NSub", 1.00e-307 - 1.01e-307);
|
||||
|
||||
printf("NaN : %4g 0x%02x%02x%02x%02x%02x%02x%02x%02x (%2d, %2d)\n",
|
||||
my_nan,
|
||||
((unsigned char *)&my_nan)[0],
|
||||
|
20
trionan.h
20
trionan.h
@ -23,6 +23,15 @@
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum {
|
||||
TRIO_FP_INFINITE,
|
||||
TRIO_FP_NAN,
|
||||
TRIO_FP_NORMAL,
|
||||
TRIO_FP_SUBNORMAL,
|
||||
TRIO_FP_ZERO
|
||||
};
|
||||
|
||||
/*
|
||||
* Return NaN (Not-a-Number).
|
||||
*/
|
||||
@ -49,6 +58,17 @@ TRIO_PUBLIC int trio_isnan(double number);
|
||||
*/
|
||||
TRIO_PUBLIC int trio_isinf(double number);
|
||||
|
||||
/*
|
||||
* If number is finite return non-zero, otherwise return zero.
|
||||
*/
|
||||
TRIO_PUBLIC int trio_isfinite(double number);
|
||||
|
||||
TRIO_PUBLIC int trio_signbit(double number);
|
||||
|
||||
TRIO_PUBLIC int trio_fpclassify(double number);
|
||||
|
||||
TRIO_PUBLIC double trio_nzero(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
43
xpath.c
43
xpath.c
@ -155,9 +155,9 @@ xmlXPathIsInf(double val) {
|
||||
*
|
||||
* Returns 1 if the value is Negative, 0 if positive
|
||||
*/
|
||||
int
|
||||
static int
|
||||
xmlXPathGetSign(double val) {
|
||||
return(trio_get_sign(val));
|
||||
return(trio_signbit(val));
|
||||
}
|
||||
|
||||
|
||||
@ -1275,8 +1275,8 @@ static const char *xmlXPathErrorMessages[] = {
|
||||
* Formats an error message.
|
||||
*/
|
||||
void
|
||||
xmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file,
|
||||
int line, int no) {
|
||||
xmlXPatherror(xmlXPathParserContextPtr ctxt, ATTRIBUTE_UNUSED const char *file,
|
||||
ATTRIBUTE_UNUSED int line, int no) {
|
||||
int n;
|
||||
const xmlChar *cur;
|
||||
const xmlChar *base;
|
||||
@ -4472,7 +4472,12 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
||||
arg2 = valuePop(ctxt);
|
||||
/* no break on purpose */
|
||||
case XPATH_NUMBER:
|
||||
ret = (arg1->floatval == arg2->floatval);
|
||||
/* Hand checking NaNs for VC6++'s benefit... */
|
||||
if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = (arg1->floatval == arg2->floatval);
|
||||
}
|
||||
break;
|
||||
case XPATH_USERS:
|
||||
case XPATH_POINT:
|
||||
@ -4508,7 +4513,12 @@ xmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
|
||||
valuePush(ctxt, arg1);
|
||||
xmlXPathNumberFunction(ctxt, 1);
|
||||
arg1 = valuePop(ctxt);
|
||||
ret = (arg1->floatval == arg2->floatval);
|
||||
/* Hand checking NaNs for VC6++'s benefit... */
|
||||
if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
|
||||
ret = 0;
|
||||
} else {
|
||||
ret = (arg1->floatval == arg2->floatval);
|
||||
}
|
||||
break;
|
||||
case XPATH_USERS:
|
||||
case XPATH_POINT:
|
||||
@ -4610,14 +4620,19 @@ xmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
|
||||
* Add tests for infinity and nan
|
||||
* => feedback on 3.4 for Inf and NaN
|
||||
*/
|
||||
if (inf && strict)
|
||||
ret = (arg1->floatval < arg2->floatval);
|
||||
else if (inf && !strict)
|
||||
ret = (arg1->floatval <= arg2->floatval);
|
||||
else if (!inf && strict)
|
||||
ret = (arg1->floatval > arg2->floatval);
|
||||
else if (!inf && !strict)
|
||||
ret = (arg1->floatval >= arg2->floatval);
|
||||
/* Hand checking NaNs for VC++6's benefit... */
|
||||
if (xmlXPathIsNaN(arg1->floatval) || xmlXPathIsNaN(arg2->floatval)) {
|
||||
ret=0;
|
||||
} else {
|
||||
if (inf && strict)
|
||||
ret = (arg1->floatval < arg2->floatval);
|
||||
else if (inf && !strict)
|
||||
ret = (arg1->floatval <= arg2->floatval);
|
||||
else if (!inf && strict)
|
||||
ret = (arg1->floatval > arg2->floatval);
|
||||
else if (!inf && !strict)
|
||||
ret = (arg1->floatval >= arg2->floatval);
|
||||
}
|
||||
xmlXPathFreeObject(arg1);
|
||||
xmlXPathFreeObject(arg2);
|
||||
return(ret);
|
||||
|
Loading…
x
Reference in New Issue
Block a user