sandygao 2002/11/20 15:43:46 Modified: java/src/org/apache/xerces/impl/dv/xs DoubleDV.java FloatDV.java Log: 1. Rec issue R-22 suggests that 0 and -0 are the same value for float/double. Making necessary changes for order comparison (0 no longer greater than -0). 2. Generating correct canonical representations for float/double. We were relying on Java to do the job, but apparently, Java Float/Double don't do what we want. Revision Changes Path 1.5 +89 -10 xml-xerces/java/src/org/apache/xerces/impl/dv/xs/DoubleDV.java Index: DoubleDV.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/dv/xs/DoubleDV.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- DoubleDV.java 18 Nov 2002 23:10:10 -0000 1.4 +++ DoubleDV.java 20 Nov 2002 23:43:46 -0000 1.5 @@ -118,6 +118,7 @@ return false; XDouble oval = (XDouble)val; + // NOTE: we don't distinguish 0.0 from -0.0 if (value == oval.value) return true; @@ -136,16 +137,25 @@ // this > other if (value > oval) return 1; + // this == other + // NOTE: we don't distinguish 0.0 from -0.0 + if (value == oval) + return 0; - // get the bits - long bits = Double.doubleToLongBits(value); - long obits = Double.doubleToLongBits(oval); - - // equal, or one is NaN, which is always smaller - return (bits == obits ? 0 : - (bits < obits ? -1 : - 1)); + // one of the 2 values or both is/are NaN(s) + + if (value != value) { + // this = NaN = other + if (oval != oval) + return 0; + // this is this = NaN > other + return 1; + } + + // this < NaN = other + return -1; } + private String canonical; public synchronized String toString() { if (canonical == null) { @@ -153,8 +163,77 @@ canonical = "INF"; else if (value == Double.NEGATIVE_INFINITY) canonical = "-INF"; - else + else if (value != value) + canonical = "NaN"; + // NOTE: we don't distinguish 0.0 from -0.0 + else if (value == 0) + canonical = "0.0E1"; + else { + // REVISIT: use the java algorithm for now, because we + // don't know what to output for 1.1d (which is no + // actually 1.1) canonical = Double.toString(value); + // if it contains 'E', then it should be a valid schema + // canonical representation + if (canonical.indexOf('E') == -1) { + int len = canonical.length(); + // at most 3 longer: E, -, 9 + char[] chars = new char[len+3]; + canonical.getChars(0, len, chars, 0); + // expected decimal point position + int edp = chars[0] == '-' ? 2 : 1; + // for non-zero integer part + if (value >= 1 || value <= -1) { + // decimal point position + int dp = canonical.indexOf('.'); + // move the digits: ddd.d --> d.ddd + for (int i = dp; i > edp; i--) { + chars[i] = chars[i-1]; + } + chars[edp] = '.'; + // trim trailing zeros: d00.0 --> d.000 --> d. + while (chars[len-1] == '0') + len--; + // add the last zero if necessary: d. --> d.0 + if (chars[len-1] == '.') + len++; + // append E: d.dd --> d.ddE + chars[len++] = 'E'; + // how far we shifted the decimal point + int shift = dp - edp; + // append the exponent --> d.ddEd + // the exponent is at most 7 + chars[len++] = (char)(shift + '0'); + } + else { + // non-zero digit point + int nzp = edp + 1; + // skip zeros: 0.003 + while (chars[nzp] == '0') + nzp++; + // put the first non-zero digit to the left of '.' + chars[edp-1] = chars[nzp]; + chars[edp] = '.'; + // move other digits (non-zero) to the right of '.' + for (int i = nzp+1, j = edp+1; i < len; i++, j++) + chars[j] = chars[i]; + // adjust the length + len -= nzp - edp; + // append 0 if nessary: 0.03 --> 3. --> 3.0 + if (len == edp + 1) + chars[len++] = '0'; + // append E-: d.dd --> d.ddE- + chars[len++] = 'E'; + chars[len++] = '-'; + // how far we shifted the decimal point + int shift = nzp - edp; + // append the exponent --> d.ddEd + // the exponent is at most 3 + chars[len++] = (char)(shift + '0'); + } + canonical = new String(chars, 0, len); + } + } } return canonical; } 1.5 +90 -11 xml-xerces/java/src/org/apache/xerces/impl/dv/xs/FloatDV.java Index: FloatDV.java =================================================================== RCS file: /home/cvs/xml-xerces/java/src/org/apache/xerces/impl/dv/xs/FloatDV.java,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- FloatDV.java 18 Nov 2002 23:10:10 -0000 1.4 +++ FloatDV.java 20 Nov 2002 23:43:46 -0000 1.5 @@ -118,6 +118,7 @@ return false; XFloat oval = (XFloat)val; + // NOTE: we don't distinguish 0.0 from -0.0 if (value == oval.value) return true; @@ -136,16 +137,25 @@ // this > other if (value > oval) return 1; - - // get the bits - int bits = Float.floatToIntBits(value); - int obits = Float.floatToIntBits(oval); - - // equal, or one is NaN, which is always smaller - return (bits == obits ? 0 : - (bits < obits ? -1 : - 1)); + // this == other + // NOTE: we don't distinguish 0.0 from -0.0 + if (value == oval) + return 0; + + // one of the 2 values or both is/are NaN(s) + + if (value != value) { + // this = NaN = other + if (oval != oval) + return 0; + // this is this = NaN > other + return 1; + } + + // this < NaN = other + return -1; } + private String canonical; public synchronized String toString() { if (canonical == null) { @@ -153,8 +163,77 @@ canonical = "INF"; else if (value == Float.NEGATIVE_INFINITY) canonical = "-INF"; - else + else if (value != value) + canonical = "NaN"; + // NOTE: we don't distinguish 0.0 from -0.0 + else if (value == 0) + canonical = "0.0E1"; + else { + // REVISIT: use the java algorithm for now, because we + // don't know what to output for 1.1f (which is no + // actually 1.1) canonical = Float.toString(value); + // if it contains 'E', then it should be a valid schema + // canonical representation + if (canonical.indexOf('E') == -1) { + int len = canonical.length(); + // at most 3 longer: E, -, 9 + char[] chars = new char[len+3]; + canonical.getChars(0, len, chars, 0); + // expected decimal point position + int edp = chars[0] == '-' ? 2 : 1; + // for non-zero integer part + if (value >= 1 || value <= -1) { + // decimal point position + int dp = canonical.indexOf('.'); + // move the digits: ddd.d --> d.ddd + for (int i = dp; i > edp; i--) { + chars[i] = chars[i-1]; + } + chars[edp] = '.'; + // trim trailing zeros: d00.0 --> d.000 --> d. + while (chars[len-1] == '0') + len--; + // add the last zero if necessary: d. --> d.0 + if (chars[len-1] == '.') + len++; + // append E: d.dd --> d.ddE + chars[len++] = 'E'; + // how far we shifted the decimal point + int shift = dp - edp; + // append the exponent --> d.ddEd + // the exponent is at most 7 + chars[len++] = (char)(shift + '0'); + } + else { + // non-zero digit point + int nzp = edp + 1; + // skip zeros: 0.003 + while (chars[nzp] == '0') + nzp++; + // put the first non-zero digit to the left of '.' + chars[edp-1] = chars[nzp]; + chars[edp] = '.'; + // move other digits (non-zero) to the right of '.' + for (int i = nzp+1, j = edp+1; i < len; i++, j++) + chars[j] = chars[i]; + // adjust the length + len -= nzp - edp; + // append 0 if nessary: 0.03 --> 3. --> 3.0 + if (len == edp + 1) + chars[len++] = '0'; + // append E-: d.dd --> d.ddE- + chars[len++] = 'E'; + chars[len++] = '-'; + // how far we shifted the decimal point + int shift = nzp - edp; + // append the exponent --> d.ddEd + // the exponent is at most 3 + chars[len++] = (char)(shift + '0'); + } + canonical = new String(chars, 0, len); + } + } } return canonical; }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]