Update for double conversion using JDK.
Project: http://git-wip-us.apache.org/repos/asf/vxquery/repo Commit: http://git-wip-us.apache.org/repos/asf/vxquery/commit/c4008e7f Tree: http://git-wip-us.apache.org/repos/asf/vxquery/tree/c4008e7f Diff: http://git-wip-us.apache.org/repos/asf/vxquery/diff/c4008e7f Branch: refs/heads/master Commit: c4008e7f9fd42a2fd1b04919c5e10cd981ff3455 Parents: 054369a Author: Eldon Carman <[email protected]> Authored: Tue Mar 31 13:37:23 2015 -0700 Committer: Eldon Carman <[email protected]> Committed: Wed Apr 1 11:34:54 2015 -0700 ---------------------------------------------------------------------- src/site/apt/join_the_community.apt | 61 ------- .../functions/cast/CastToDoubleOperation.java | 171 +++---------------- 2 files changed, 28 insertions(+), 204 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/vxquery/blob/c4008e7f/src/site/apt/join_the_community.apt ---------------------------------------------------------------------- diff --git a/src/site/apt/join_the_community.apt b/src/site/apt/join_the_community.apt deleted file mode 100644 index 75c6b07..0000000 --- a/src/site/apt/join_the_community.apt +++ /dev/null @@ -1,61 +0,0 @@ -~~ Licensed to the Apache Software Foundation (ASF) under one or more -~~ contributor license agreements. See the NOTICE file distributed with -~~ this work for additional information regarding copyright ownership. -~~ The ASF licenses this file to You under the Apache License, Version 2.0 -~~ (the "License"); you may not use this file except in compliance with -~~ the License. You may obtain a copy of the License at -~~ -~~ http://www.apache.org/licenses/LICENSE-2.0 -~~ -~~ Unless required by applicable law or agreed to in writing, software -~~ distributed under the License is distributed on an "AS IS" BASIS, -~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -~~ See the License for the specific language governing permissions and -~~ limitations under the License. - -Joining the Apache VXQuery Community - - The following steps are here to help new Apache VXQuery developer get up to speed. - These steps will connect you with the community and give you a place to start. - -* Community Member - - * Sign up for the mailing list: [email protected] - - * Download the latest release and run a few queries. - - * {{{http://vxquery.apache.org/user_installation.html}Installation instructions}}. - - * {{{http://vxquery.apache.org/user_query.html}Execute a query}}. - - * If you want more information on XQuery: - - * Go through the {{{http://www.w3schools.com/xquery/}W3Schools XQuery tutorial}}. - - * Review the {{{http://www.w3.org/TR/xquery/}XQuery specification}}. - -* Developer - - * Go through the community member steps. - - * Setup your eclipse development environment. - - * {{{http://vxquery.apache.org/development_eclipse_setup.html}Setup instructions}}. - - * XQuery has a test suite to verify XQuery specifications. - - * Run the test suite for XQTS. - - * {{{http://vxquery.apache.org/user_running_tests.html}Testing instructions}}. - - * Review the test structure. - - * Code is found in the "VXQuery XTest" module. - - * Review open issues for the project. - - * {{{http://vxquery.apache.org/issue-tracking.html}Issues list}}. - - - - http://git-wip-us.apache.org/repos/asf/vxquery/blob/c4008e7f/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/cast/CastToDoubleOperation.java ---------------------------------------------------------------------- diff --git a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/cast/CastToDoubleOperation.java b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/cast/CastToDoubleOperation.java index 499c1d3..13bb1f0 100644 --- a/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/cast/CastToDoubleOperation.java +++ b/vxquery-core/src/main/java/org/apache/vxquery/runtime/functions/cast/CastToDoubleOperation.java @@ -37,13 +37,6 @@ import edu.uci.ics.hyracks.data.std.primitive.ShortPointable; import edu.uci.ics.hyracks.data.std.primitive.UTF8StringPointable; public class CastToDoubleOperation extends AbstractCastToOperation { - /* - * All the positive powers of 10 that can be represented exactly in float. - */ - private static final double powersOf10[] = { 1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, - 1.0e10, 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15, 1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20, 1.0e21, 1.0e22 }; - private static final double powersOf2[] = { 1.0e16d, 1.0e32f, 1.0e64, 1.0e128, 1.0e256 }; - @Override public void convertBoolean(BooleanPointable boolp, DataOutput dOut) throws SystemException, IOException { double value = (boolp.getBoolean() ? 1 : 0); @@ -73,30 +66,24 @@ public class CastToDoubleOperation extends AbstractCastToOperation { @Override public void convertInteger(LongPointable longp, DataOutput dOut) throws SystemException, IOException { - double value = longp.doubleValue(); - dOut.write(ValueTag.XS_DOUBLE_TAG); - dOut.writeDouble(value); + writeIntegerAsDouble(longp, dOut); } @Override public void convertString(UTF8StringPointable stringp, DataOutput dOut) throws SystemException, IOException { ICharacterIterator charIterator = new UTF8StringCharacterIterator(stringp); charIterator.reset(); - short decimalPlace = 0; - long value = 0; double valueDouble; - boolean pastDecimal = false, negativeValue = false; + boolean negativeValue = false; int c = ICharacterIterator.EOS_CHAR; int c2 = ICharacterIterator.EOS_CHAR; int c3 = ICharacterIterator.EOS_CHAR; - long limit = -Long.MAX_VALUE; // Check sign. c = charIterator.next(); if (c == Character.valueOf('-')) { negativeValue = true; c = charIterator.next(); - limit = Long.MIN_VALUE; } // Check the special cases. if (c == Character.valueOf('I') || c == Character.valueOf('N')) { @@ -105,128 +92,26 @@ public class CastToDoubleOperation extends AbstractCastToOperation { if (charIterator.next() != ICharacterIterator.EOS_CHAR) { throw new SystemException(ErrorCode.FORG0001); } else if (c == Character.valueOf('I') && c2 == Character.valueOf('N') && c3 == Character.valueOf('F')) { - valueDouble = Double.NEGATIVE_INFINITY; + valueDouble = Double.POSITIVE_INFINITY; } else if (c == Character.valueOf('N') && c2 == Character.valueOf('a') && c3 == Character.valueOf('N')) { valueDouble = Double.NaN; } else { throw new SystemException(ErrorCode.FORG0001); } + dOut.write(ValueTag.XS_DOUBLE_TAG); + dOut.writeDouble((negativeValue ? -valueDouble : valueDouble)); } else { - // Read in the number. - do { - if (Character.isDigit(c)) { - if (value < limit / 10 + Character.getNumericValue(c)) { - throw new SystemException(ErrorCode.FOCA0006); - } - value = value * 10 - Character.getNumericValue(c); - if (pastDecimal) { - decimalPlace--; - } - } else if (c == Character.valueOf('.') && pastDecimal == false) { - pastDecimal = true; - } else if (c == Character.valueOf('E') || c == Character.valueOf('e')) { - break; - } else { - throw new SystemException(ErrorCode.FORG0001); - } - } while ((c = charIterator.next()) != ICharacterIterator.EOS_CHAR); - - // Parse the exponent. - if (c == Character.valueOf('E') || c == Character.valueOf('e')) { - int moveOffset = 0; - boolean negativeOffset = false; - // Check for the negative sign. - c = charIterator.next(); - if (c == Character.valueOf('-')) { - negativeOffset = true; - c = charIterator.next(); - } - // Process the numeric value. - do { - if (Character.isDigit(c)) { - moveOffset = moveOffset * 10 + Character.getNumericValue(c); - } else { - throw new SystemException(ErrorCode.FORG0001); - } - } while ((c = charIterator.next()) != ICharacterIterator.EOS_CHAR); - if (moveOffset > 324 || moveOffset < -324) { - throw new SystemException(ErrorCode.FOCA0006); - } - decimalPlace += (negativeOffset ? -moveOffset : moveOffset); - } - - /* - * The following conditions to create the floating point value is using known valid float values. - * In addition, each one only needs one or two operations to get the float value, further minimizing - * possible errors. (Not perfect, but pretty good.) - */ - valueDouble = (double) value; - if (decimalPlace == 0 || valueDouble == 0.0f) { - // No modification required to float value. - } else if (decimalPlace >= 0) { - if (decimalPlace <= 16) { - valueDouble *= powersOf10[decimalPlace]; - } else { - // Multiply the value based on the exponent binary. - if ((decimalPlace & 15) != 0) { - valueDouble *= powersOf10[decimalPlace & 15]; - } - if ((decimalPlace >>= 4) != 0) { - int j; - for (j = 0; decimalPlace > 1; j++, decimalPlace >>= 1) { - if ((decimalPlace & 1) != 0) - valueDouble *= powersOf2[j]; - } - // Handle the last cast for infinity and max value. - double t = valueDouble * powersOf2[j]; - if (Double.isInfinite(t)) { - // Overflow - t = valueDouble / 2.0; - t *= powersOf2[j]; - if (Double.isInfinite(t)) { - valueDouble = Double.POSITIVE_INFINITY; - } - t = -Double.MAX_VALUE; - } - valueDouble = t; - } - } - } else { - if (decimalPlace >= -16) { - valueDouble /= powersOf10[-decimalPlace]; - } else { - if ((decimalPlace & 15) != 0) { - valueDouble /= powersOf10[decimalPlace & 15]; - } - if ((decimalPlace >>= 4) != 0) { - int j; - for (j = 0; decimalPlace > 1; j++, decimalPlace >>= 1) { - if ((decimalPlace & 1) != 0) - valueDouble /= powersOf2[j]; - } - // Handle the last cast for zero and min value. - double t = valueDouble / powersOf2[j]; - if (t == 0.0) { - // Underflow. - t = valueDouble * 2.0; - t /= powersOf2[j]; - if (t == 0.0) { - valueDouble = 0.0; - } - t = Double.MIN_VALUE; - } - valueDouble = t; - } - } + // We create an object to keep the conversion algorithm simple and improve precision. + // While a better solution may be available this will hold us over until then. + StringBuilder sb = new StringBuilder(); + stringp.toString(sb); + try { + valueDouble = Double.parseDouble(sb.toString()); + } catch (NumberFormatException e) { + throw new SystemException(ErrorCode.FORG0001); } - - } - - dOut.write(ValueTag.XS_DOUBLE_TAG); - if (valueDouble == 0.0) { - dOut.writeDouble((negativeValue ? -0.0 : 0.0)); - } else { - dOut.writeDouble((negativeValue ? valueDouble : -valueDouble)); + dOut.write(ValueTag.XS_DOUBLE_TAG); + dOut.writeDouble(valueDouble); } } @@ -239,54 +124,54 @@ public class CastToDoubleOperation extends AbstractCastToOperation { * Derived Datatypes */ public void convertByte(BytePointable bytep, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(bytep, dOut); + writeIntegerAsDouble(bytep, dOut); } public void convertInt(IntegerPointable intp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(intp, dOut); + writeIntegerAsDouble(intp, dOut); } public void convertLong(LongPointable longp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(longp, dOut); + writeIntegerAsDouble(longp, dOut); } public void convertNegativeInteger(LongPointable longp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(longp, dOut); + writeIntegerAsDouble(longp, dOut); } public void convertNonNegativeInteger(LongPointable longp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(longp, dOut); + writeIntegerAsDouble(longp, dOut); } public void convertNonPositiveInteger(LongPointable longp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(longp, dOut); + writeIntegerAsDouble(longp, dOut); } public void convertPositiveInteger(LongPointable longp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(longp, dOut); + writeIntegerAsDouble(longp, dOut); } public void convertShort(ShortPointable shortp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(shortp, dOut); + writeIntegerAsDouble(shortp, dOut); } public void convertUnsignedByte(ShortPointable shortp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(shortp, dOut); + writeIntegerAsDouble(shortp, dOut); } public void convertUnsignedInt(LongPointable longp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(longp, dOut); + writeIntegerAsDouble(longp, dOut); } public void convertUnsignedLong(LongPointable longp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(longp, dOut); + writeIntegerAsDouble(longp, dOut); } public void convertUnsignedShort(IntegerPointable intp, DataOutput dOut) throws SystemException, IOException { - writeDoubleValue(intp, dOut); + writeIntegerAsDouble(intp, dOut); } - private void writeDoubleValue(INumeric numericp, DataOutput dOut) throws SystemException, IOException { + private void writeIntegerAsDouble(INumeric numericp, DataOutput dOut) throws SystemException, IOException { dOut.write(ValueTag.XS_DOUBLE_TAG); dOut.writeDouble(numericp.doubleValue()); }
