Download
Getting Started
Members
Projects
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
More
Community
Marketplace
Events
Planet Eclipse
Newsletter
Videos
Participate
Report a Bug
Forums
Mailing Lists
Wiki
IRC
How to Contribute
Working Groups
Automotive
Internet of Things
LocationTech
Long-Term Support
PolarSys
Science
OpenMDM
Toggle navigation
Bugzilla – Attachment 14808 Details for
Bug 74126
Compiler should support new hexadecimal floating-point literals
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
Terms of Use
|
Copyright Agent
[patch]
Patch to o.e.jdt.core project
jdt-core-patch-20040927.txt (text/plain), 26.56 KB, created by
Jim des Rivieres
on 2004-09-27 17:04:50 EDT
(
hide
)
Description:
Patch to o.e.jdt.core project
Filename:
MIME Type:
Creator:
Jim des Rivieres
Created:
2004-09-27 17:04:50 EDT
Size:
26.56 KB
patch
obsolete
>Index: compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java >=================================================================== >RCS file: /data/cvs/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java,v >retrieving revision 1.10 >diff -u -r1.10 DoubleLiteral.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java 21 Sep 2004 17:41:33 -0000 1.10 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/DoubleLiteral.java 27 Sep 2004 20:52:29 -0000 >@@ -10,11 +10,12 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >+import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.compiler.ASTVisitor; > import org.eclipse.jdt.internal.compiler.impl.*; > import org.eclipse.jdt.internal.compiler.codegen.*; > import org.eclipse.jdt.internal.compiler.lookup.*; >-import org.eclipse.jdt.internal.compiler.util.Util; >+import org.eclipse.jdt.internal.compiler.util.FloatUtil; > > public class DoubleLiteral extends NumberLiteral { > double value; >@@ -22,44 +23,66 @@ > super(token, s, e); > } > public void computeConstant() { >- //the source is correctly formated so the exception should never occurs >+ if (CharOperation.indexOf('x', source) >= 0 >+ && CharOperation.indexOf('p', source) >= 0) { >+ // hex floating point literal >+ try { >+ double v = FloatUtil.valueOfHexDoubleLiteral(source); >+ if (v == Double.POSITIVE_INFINITY) { >+ // error: the number is too large to represent >+ return; >+ } >+ if (Double.isNaN(v)) { >+ // error: the number is too small to represent >+ return; >+ } >+ value = v; >+ constant = Constant.fromValue(v); >+ } catch (NumberFormatException e) { >+ // the source is correctly formated so the exception should never occurs >+ return; >+ } >+ } >+ >+ // non-hexadecimal floating point literals > Double computedValue; > try { > computedValue = Double.valueOf(String.valueOf(source)); > } catch (NumberFormatException e) { >- /* >- * this can happen if this is an hexadecimal floating-point literal and the libraries used >- * are < 1.5 >- */ >- computedValue = new Double(Util.getFloatingPoint(source)); >+ // the source is correctly formated so the exception should never occurs >+ return; > } > > final double doubleValue = computedValue.doubleValue(); >- if (doubleValue > Double.MAX_VALUE) >- return; //may be Infinity >- if (doubleValue < Double.MIN_VALUE) { //only a true 0 can be made of zeros >- //2.00000000000000000e-324 is illegal .... >+ if (doubleValue > Double.MAX_VALUE) { >+ // error: the number is too large to represent >+ return; >+ } >+ if (doubleValue < Double.MIN_VALUE) { >+ // see 1F6IGUU >+ // a true 0 only has '0' and '.' in mantissa >+ // 1.0e-5000d is non-zero, but underflows to 0 > label : for (int i = 0; i < source.length; i++) { //it is welled formated so just test against '0' and potential . D d > switch (source[i]) { > case '0' : > case '.' : >- case 'd' : >- case 'D' : >- case 'x' : >- case 'X' : > break; > case 'e' : > case 'E' : >- case 'p' : >- case 'P' : >- break label; //exposant are valid....! >+ // starting the exponent - mantissa is all zero >+ break label; >+ case 'f' : >+ case 'F' : >+ // no exponent - mantissa is all zero >+ break label; > default : >+ // error: the number is too small to represent > return; > } > } >- } //error >- >- constant = Constant.fromValue(value = doubleValue); >+ } >+ value = doubleValue; >+ constant = Constant.fromValue(value); > } > /** > * Code generation for the double literak >Index: compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java >=================================================================== >RCS file: /data/cvs/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java,v >retrieving revision 1.10 >diff -u -r1.10 FloatLiteral.java >--- compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java 21 Sep 2004 17:41:33 -0000 1.10 >+++ compiler/org/eclipse/jdt/internal/compiler/ast/FloatLiteral.java 27 Sep 2004 20:52:29 -0000 >@@ -10,12 +10,13 @@ > *******************************************************************************/ > package org.eclipse.jdt.internal.compiler.ast; > >+import org.eclipse.jdt.core.compiler.CharOperation; > import org.eclipse.jdt.internal.compiler.ASTVisitor; > import org.eclipse.jdt.internal.compiler.codegen.CodeStream; > import org.eclipse.jdt.internal.compiler.impl.Constant; > import org.eclipse.jdt.internal.compiler.lookup.BlockScope; > import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; >-import org.eclipse.jdt.internal.compiler.util.Util; >+import org.eclipse.jdt.internal.compiler.util.FloatUtil; > > public class FloatLiteral extends NumberLiteral { > float value; >@@ -24,45 +25,66 @@ > super(token, s, e); > } > public void computeConstant() { >- //the source is correctly formated so the exception should never occurs >+ if (CharOperation.indexOf('x', source) >= 0 >+ && CharOperation.indexOf('p', source) >= 0) { >+ // hex floating point literal >+ try { >+ float v = FloatUtil.valueOfHexFloatLiteral(source); >+ if (v == Float.POSITIVE_INFINITY) { >+ // error: the number is too large to represent >+ return; >+ } >+ if (Float.isNaN(v)) { >+ // error: the number is too small to represent >+ return; >+ } >+ value = v; >+ constant = Constant.fromValue(v); >+ } catch (NumberFormatException e) { >+ // the source is correctly formated so the exception should never occurs >+ return; >+ } >+ } >+ >+ // non-hexadecimal floating point literals > Float computedValue; > try { > computedValue = Float.valueOf(String.valueOf(source)); > } catch (NumberFormatException e) { >- /* >- * this can happen if this is an hexadecimal floating-point literal and the libraries used >- * are < 1.5 >- */ >- computedValue = new Float(Util.getFloatingPoint(source)); >+ // the source is correctly formated so the exception should never occurs >+ return; > } > >- if (computedValue.doubleValue() > Float.MAX_VALUE) { >- return; //may be Infinity >+ final float floatValue = computedValue.floatValue(); >+ if (floatValue > Float.MAX_VALUE) { >+ // error: the number is too large to represent >+ return; > } >- if (computedValue.floatValue() < Float_MIN_VALUE) { >+ if (floatValue < Float_MIN_VALUE) { > // see 1F6IGUU >- //only a true 0 can be made of zeros >- //1.00000000e-46f is illegal .... >+ // a true 0 only has '0' and '.' in mantissa >+ // 1.0e-5000f is non-zero, but underflows to 0 > label : for (int i = 0; i < source.length; i++) { > switch (source[i]) { > case '.' : >- case 'f' : >- case 'F' : > case '0' : >- case 'x' : >- case 'X' : > break; > case 'e' : > case 'E' : >- case 'p' : >- case 'P' : >- break label; //exposant are valid !.... >+ // starting the exponent - mantissa is all zero >+ break label; >+ case 'd' : >+ case 'D' : >+ // no exponent - mantissa is all zero >+ break label; > default : >- return; //error >+ // error: the number is too small to represent >+ return; > } > } > } >- constant = Constant.fromValue(value = computedValue.floatValue()); >+ value = floatValue; >+ constant = Constant.fromValue(value); > } > /** > * Code generation for float literal >Index: compiler/org/eclipse/jdt/internal/compiler/util/Util.java >=================================================================== >RCS file: /data/cvs/eclipse/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/util/Util.java,v >retrieving revision 1.41 >diff -u -r1.41 Util.java >--- compiler/org/eclipse/jdt/internal/compiler/util/Util.java 21 Sep 2004 17:41:33 -0000 1.41 >+++ compiler/org/eclipse/jdt/internal/compiler/util/Util.java 27 Sep 2004 20:52:29 -0000 >@@ -520,220 +520,4 @@ > return Boolean.FALSE; > } > } >- >- /** >- * Returns the double value corresponding to the hexadecimal floating-point literal >- * @return the double value corresponding to the hexadecimal floating-point literal >- */ >- public static double getFloatingPoint(char[] source) { >- int length = source.length; >- long hexValue = 0; >- int i = 2; >- loop: while (true) { >- switch(source[i]) { >- case '0' : >- hexValue <<= 4; >- break; >- case '1' : >- hexValue <<= 4; >- hexValue ++; >- break; >- case '2' : >- hexValue <<= 4; >- hexValue += 2; >- break; >- case '3' : >- hexValue <<= 4; >- hexValue += 3; >- break; >- case '4' : >- hexValue <<= 4; >- hexValue += 4; >- break; >- case '5' : >- hexValue <<= 4; >- hexValue += 5; >- break; >- case '6' : >- hexValue <<= 4; >- hexValue += 6; >- break; >- case '7' : >- hexValue <<= 4; >- hexValue += 7; >- break; >- case '8' : >- hexValue <<= 4; >- hexValue += 8; >- break; >- case '9' : >- hexValue <<= 4; >- hexValue += 9; >- break; >- case 'a' : >- case 'A' : >- hexValue <<= 4; >- hexValue += 10; >- break; >- case 'b' : >- case 'B' : >- hexValue <<= 4; >- hexValue += 11; >- break; >- case 'c' : >- case 'C' : >- hexValue <<= 4; >- hexValue += 12; >- break; >- case 'd' : >- case 'D' : >- hexValue <<= 4; >- hexValue += 13; >- break; >- case 'e' : >- case 'E' : >- hexValue <<= 4; >- hexValue += 14; >- break; >- case 'F' : >- case 'f' : >- hexValue <<= 4; >- hexValue += 15; >- break; >- default: >- break loop; >- } >- i++; >- } >- double decimalsValue = 0.0; >- if (source[i] == '.') { >- int index = 1; >- i++; >- loop2 : while (true) { >- switch(source[i]) { >- case '1' : >- decimalsValue += 1.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case '2' : >- decimalsValue += 2.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case '3' : >- decimalsValue += 3.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case '4' : >- decimalsValue += 4.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case '5' : >- decimalsValue += 5.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case '6' : >- decimalsValue += 6.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case '7' : >- decimalsValue += 7.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case '8' : >- decimalsValue += 8.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case '9' : >- decimalsValue += 9.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case 'a' : >- case 'A' : >- decimalsValue += 10.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case 'b' : >- case 'B' : >- decimalsValue += 11.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case 'c' : >- case 'C' : >- decimalsValue += 12.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case 'd' : >- case 'D' : >- decimalsValue += 13.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case 'e' : >- case 'E' : >- decimalsValue += 14.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- case 'F' : >- case 'f' : >- decimalsValue += 15.0 / ((2 << 3) << (4 * (index - 1))); >- break; >- default: >- break loop2; >- } >- i++; >- index++; >- } >- } >- i++; // read p or P >- boolean isNegative = false; >- switch(source[i]) { >- case '-' : >- isNegative = true; >- i++; >- break; >- case '+' : >- i++; >- break; >- } >- int exponentValue = 0; >- loop3: while (true) { >- switch(source[i]) { >- case '0' : >- exponentValue *= 10; >- break; >- case '1' : >- exponentValue *= 10; >- exponentValue++; >- break; >- case '2' : >- exponentValue *= 10; >- exponentValue += 2; >- break; >- case '3' : >- exponentValue *= 10; >- exponentValue += 3; >- break; >- case '4' : >- exponentValue *= 10; >- exponentValue += 4; >- break; >- case '5' : >- exponentValue *= 10; >- exponentValue += 5; >- break; >- case '6' : >- exponentValue *= 10; >- exponentValue += 6; >- break; >- case '7' : >- exponentValue *= 10; >- exponentValue += 7; >- break; >- case '8' : >- exponentValue *= 10; >- exponentValue += 8; >- break; >- case '9' : >- exponentValue *= 10; >- exponentValue += 9; >- break; >- default: >- break loop3; >- } >- i++; >- if (i >= length) { >- break loop3; >- } >- } >- if (exponentValue == 0) { >- return hexValue + decimalsValue; >- } >- exponentValue--; >- return (hexValue + decimalsValue) * (isNegative ? 1.0 / (2 << exponentValue) : 2 << exponentValue); >- } > } >Index: compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java >=================================================================== >RCS file: compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java >diff -N compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java >--- /dev/null 1 Jan 1970 00:00:00 -0000 >+++ compiler/org/eclipse/jdt/internal/compiler/util/FloatUtil.java 1 Jan 1970 00:00:00 -0000 >@@ -0,0 +1,421 @@ >+/******************************************************************************* >+ * Copyright (c) 2004 IBM Corporation and others. >+ * All rights reserved. This program and the accompanying materials >+ * are made available under the terms of the Common Public License v1.0 >+ * which accompanies this distribution, and is available at >+ * http://www.eclipse.org/legal/cpl-v10.html >+ * >+ * Contributors: >+ * IBM Corporation - initial API and implementation >+ *******************************************************************************/ >+package org.eclipse.jdt.internal.compiler.util; >+ >+/** >+ * Internal utility for declaing with hexadecimal double and float literals. >+ * >+ * @since 3.1 >+ */ >+public class FloatUtil { >+ >+ private static final int DOUBLE_FRACTION_WIDTH = 52; >+ >+ private static final int DOUBLE_PRECISION = 53; >+ >+ private static final int MAX_DOUBLE_EXPONENT = +1023; >+ >+ private static final int MIN_NORMALIZED_DOUBLE_EXPONENT = -1022; >+ >+ private static final int MIN_UNNORMALIZED_DOUBLE_EXPONENT = MIN_NORMALIZED_DOUBLE_EXPONENT >+ - DOUBLE_PRECISION; >+ >+ private static final int DOUBLE_EXPONENT_BIAS = +1023; >+ >+ private static final int DOUBLE_EXPONENT_SHIFT = 52; >+ >+ private static final int SINGLE_FRACTION_WIDTH = 23; >+ >+ private static final int SINGLE_PRECISION = 24; >+ >+ private static final int MAX_SINGLE_EXPONENT = +127; >+ >+ private static final int MIN_NORMALIZED_SINGLE_EXPONENT = -126; >+ >+ private static final int MIN_UNNORMALIZED_SINGLE_EXPONENT = MIN_NORMALIZED_SINGLE_EXPONENT >+ - SINGLE_PRECISION; >+ >+ private static final int SINGLE_EXPONENT_BIAS = +127; >+ >+ private static final int SINGLE_EXPONENT_SHIFT = 23; >+ >+ /** >+ * Returns the float value corresponding to the given >+ * hexadecimal floating-point single precision literal. >+ * The literal must be syntactially correct, and must be >+ * a float literal (end in a 'f' or 'F'). It must not >+ * include either leading or trailing whitespace or >+ * a sign. >+ * <p> >+ * This method returns the same answer as >+ * Float.parseFloat(new String(source)) does in JDK 1.5, >+ * except that this method returns Floal.NaN if it >+ * would underflow to 0 (parseFloat just returns 0). >+ * The method handles all the tricky cases, including >+ * fraction rounding to 24 bits and gradual underflow. >+ * </p> >+ * >+ * @param source source string containing single precision >+ * hexadecimal floating-point literal >+ * @return the float value, including Float.POSITIVE_INFINITY >+ * if the non-zero value is too large to be represented, and >+ * Float.NaN if the non-zero value is too small to be represented >+ */ >+ public static float valueOfHexFloatLiteral(char[] source) { >+ long bits = convertHexFloatingPointLiteralToBits(source); >+ return Float.intBitsToFloat((int) bits); >+ } >+ >+ /** >+ * Returns the double value corresponding to the given >+ * hexadecimal floating-point double precision literal. >+ * The literal must be syntactially correct, and must be >+ * a double literal (end in an optional 'd' or 'D'). >+ * It must not include either leading or trailing whitespace or >+ * a sign. >+ * <p> >+ * This method returns the same answer as >+ * Double.parseDouble(new String(source)) does in JDK 1.5, >+ * except that this method throw NumberFormatException in >+ * the case of overflow to infinity or underflow to 0. >+ * The method handles all the tricky cases, including >+ * fraction rounding to 53 bits and gradual underflow. >+ * </p> >+ * >+ * @param source source string containing double precision >+ * hexadecimal floating-point literal >+ * @return the double value, including Double.POSITIVE_INFINITY >+ * if the non-zero value is too large to be represented, and >+ * Double.NaN if the non-zero value is too small to be represented >+ */ >+ public static double valueOfHexDoubleLiteral(char[] source) { >+ long bits = convertHexFloatingPointLiteralToBits(source); >+ return Double.longBitsToDouble(bits); >+ } >+ >+ /** >+ * Returns the given hexadecimal floating-point literal as >+ * the bits for a single-precision (float) or a >+ * double-precision (double) IEEE floating point number. >+ * The literal must be syntactially correct. It must not >+ * include either leading or trailing whitespace or a sign. >+ * >+ * @param source source string containing hexadecimal floating-point literal >+ * @return for double precision literals, bits suitable >+ * for passing to Double.longBitsToDouble; for single precision literals, >+ * bits suitable for passing to Single.intBitsToDouble in the bottom >+ * 32 bits of the result >+ * @throws NumberFormatException if the number cannot be parsed >+ */ >+ private static long convertHexFloatingPointLiteralToBits(char[] source) { >+ int length = source.length; >+ long mantissa = 0; >+ >+ // Step 1: process the '0x' lead-in >+ int next = 0; >+ char nextChar = source[next]; >+ nextChar = source[next]; >+ if (nextChar == '0') { >+ next++; >+ } else { >+ throw new NumberFormatException(); >+ } >+ nextChar = source[next]; >+ if (nextChar == 'X' || nextChar == 'x') { >+ next++; >+ } else { >+ throw new NumberFormatException(); >+ } >+ >+ // Step 2: process leading '0's either before or after the '.' >+ int binaryPointPosition = -1; >+ loop: while (true) { >+ nextChar = source[next]; >+ switch (nextChar) { >+ case '0': >+ next++; >+ continue loop; >+ case '.': >+ binaryPointPosition = next; >+ next++; >+ continue loop; >+ default: >+ break loop; >+ } >+ } >+ >+ // Step 3: process the mantissa >+ // leading zeros have been trimmed >+ int mantissaBits = 0; >+ int leadingDigitPosition = -1; >+ loop: while (true) { >+ nextChar = source[next]; >+ int hexdigit; >+ switch (nextChar) { >+ case '0': >+ case '1': >+ case '2': >+ case '3': >+ case '4': >+ case '5': >+ case '6': >+ case '7': >+ case '8': >+ case '9': >+ hexdigit = nextChar - '0'; >+ break; >+ case 'a': >+ case 'b': >+ case 'c': >+ case 'd': >+ case 'e': >+ case 'f': >+ hexdigit = (nextChar - 'a') + 10; >+ break; >+ case 'A': >+ case 'B': >+ case 'C': >+ case 'D': >+ case 'E': >+ case 'F': >+ hexdigit = (nextChar - 'A') + 10; >+ break; >+ case '.': >+ binaryPointPosition = next; >+ next++; >+ continue loop; >+ default: >+ if (binaryPointPosition < 0) { >+ // record virtual '.' as being to right of all digits >+ binaryPointPosition = next; >+ } >+ break loop; >+ } >+ if (mantissaBits == 0) { >+ // this is the first non-zero hex digit >+ // ignore leading binary 0's in hex digit >+ leadingDigitPosition = next; >+ mantissa = hexdigit; >+ mantissaBits = 4; >+ } else if (mantissaBits < 60) { >+ // middle hex digits >+ mantissa <<= 4; >+ mantissa |= hexdigit; >+ mantissaBits += 4; >+ } else { >+ // more mantissa bits than we can handle >+ // drop this hex digit on the ground >+ } >+ next++; >+ continue loop; >+ } >+ >+ // Step 4: process the 'P' >+ nextChar = source[next]; >+ if (nextChar == 'P' || nextChar == 'p') { >+ next++; >+ } else { >+ throw new NumberFormatException(); >+ } >+ >+ // Step 5: process the exponent >+ int exponent = 0; >+ int exponentSign = +1; >+ loop: while (next < length) { >+ nextChar = source[next]; >+ switch (nextChar) { >+ case '+': >+ exponentSign = +1; >+ next++; >+ continue loop; >+ case '-': >+ exponentSign = -1; >+ next++; >+ continue loop; >+ case '0': >+ case '1': >+ case '2': >+ case '3': >+ case '4': >+ case '5': >+ case '6': >+ case '7': >+ case '8': >+ case '9': >+ int digit = nextChar - '0'; >+ exponent = (exponent * 10) + digit; >+ next++; >+ continue loop; >+ default: >+ break loop; >+ } >+ } >+ >+ // Step 6: process the optional 'f' or 'd' >+ boolean doublePrecision = true; >+ if (next < length) { >+ nextChar = source[next]; >+ switch (nextChar) { >+ case 'f': >+ case 'F': >+ doublePrecision = false; >+ next++; >+ break; >+ case 'd': >+ case 'D': >+ doublePrecision = true; >+ next++; >+ break; >+ default: >+ throw new NumberFormatException(); >+ } >+ } >+ >+ // at this point, all the parsing is done >+ // Step 7: handle mantissa of zero >+ if (mantissa == 0) { >+ return 0L; >+ } >+ >+ // Step 8: normalize non-zero mantissa >+ // mantissa is in right-hand mantissaBits >+ // ensure that top bit (as opposed to hex digit) is 1 >+ int scaleFactorCompensation = 0; >+ long top = (mantissa >>> (mantissaBits - 4)); >+ if ((top & 0x8) == 0) { >+ mantissaBits--; >+ scaleFactorCompensation++; >+ if ((top & 0x4) == 0) { >+ mantissaBits--; >+ scaleFactorCompensation++; >+ if ((top & 0x2) == 0) { >+ mantissaBits--; >+ scaleFactorCompensation++; >+ } >+ } >+ } >+ >+ // Step 9: convert double literals to IEEE double >+ long result = 0L; >+ if (doublePrecision) { >+ long fraction; >+ if (mantissaBits > DOUBLE_PRECISION) { >+ // more bits than we can keep >+ int extraBits = mantissaBits - DOUBLE_PRECISION; >+ // round to DOUBLE_PRECISION bits >+ fraction = mantissa >>> (extraBits - 1); >+ long lowBit = fraction & 0x1; >+ fraction += lowBit; >+ fraction = fraction >>> 1; >+ if ((fraction & (1L << DOUBLE_PRECISION)) != 0) { >+ fraction = fraction >>> 1; >+ scaleFactorCompensation -= 1; >+ } >+ } else { >+ // less bits than the faction can hold - pad on right with 0s >+ fraction = mantissa << (DOUBLE_PRECISION - mantissaBits); >+ } >+ >+ int scaleFactor = 0; // how many bits to move '.' to before leading hex digit >+ if (mantissaBits > 0) { >+ if (leadingDigitPosition < binaryPointPosition) { >+ // e.g., 0x80.0p0 has scaleFactor == +8 >+ scaleFactor = 4 * (binaryPointPosition - leadingDigitPosition); >+ // e.g., 0x10.0p0 has scaleFactorCompensation == +3 >+ scaleFactor -= scaleFactorCompensation; >+ } else { >+ // e.g., 0x0.08p0 has scaleFactor == -4 >+ scaleFactor = -4 >+ * (leadingDigitPosition - binaryPointPosition - 1); >+ // e.g., 0x0.01p0 has scaleFactorCompensation == +3 >+ scaleFactor -= scaleFactorCompensation; >+ } >+ } >+ >+ int e = (exponentSign * exponent) + scaleFactor; >+ if (e - 1 > MAX_DOUBLE_EXPONENT) { >+ // overflow to +infinity >+ result = Double.doubleToLongBits(Double.POSITIVE_INFINITY); >+ } else if (e - 1 >= MIN_NORMALIZED_DOUBLE_EXPONENT) { >+ // can be represented as a normalized double >+ // the left most bit must be discarded (it's always a 1) >+ long biasedExponent = e - 1 + DOUBLE_EXPONENT_BIAS; >+ result = fraction & ~(1L << DOUBLE_FRACTION_WIDTH); >+ result |= (biasedExponent << DOUBLE_EXPONENT_SHIFT); >+ } else if (e - 1 > MIN_UNNORMALIZED_DOUBLE_EXPONENT) { >+ // can be represented as an unnormalized double >+ long biasedExponent = 0; >+ result = fraction >>> (MIN_NORMALIZED_DOUBLE_EXPONENT - e + 1); >+ result |= (biasedExponent << DOUBLE_EXPONENT_SHIFT); >+ } else { >+ // underflow - return Double.NaN >+ result = Double.doubleToLongBits(Double.NaN); >+ } >+ return result; >+ } >+ >+ // Step 10: convert float literals to IEEE single >+ long fraction; >+ if (mantissaBits > SINGLE_PRECISION) { >+ // more bits than we can keep >+ int extraBits = mantissaBits - SINGLE_PRECISION; >+ // round to DOUBLE_PRECISION bits >+ fraction = mantissa >>> (extraBits - 1); >+ long lowBit = fraction & 0x1; >+ fraction += lowBit; >+ fraction = fraction >>> 1; >+ if ((fraction & (1L << SINGLE_PRECISION)) != 0) { >+ fraction = fraction >>> 1; >+ scaleFactorCompensation -= 1; >+ } >+ } else { >+ // less bits than the faction can hold - pad on right with 0s >+ fraction = mantissa << (SINGLE_PRECISION - mantissaBits); >+ } >+ >+ int scaleFactor = 0; // how many bits to move '.' to before leading hex digit >+ if (mantissaBits > 0) { >+ if (leadingDigitPosition < binaryPointPosition) { >+ // e.g., 0x80.0p0 has scaleFactor == +8 >+ scaleFactor = 4 * (binaryPointPosition - leadingDigitPosition); >+ // e.g., 0x10.0p0 has scaleFactorCompensation == +3 >+ scaleFactor -= scaleFactorCompensation; >+ } else { >+ // e.g., 0x0.08p0 has scaleFactor == -4 >+ scaleFactor = -4 >+ * (leadingDigitPosition - binaryPointPosition - 1); >+ // e.g., 0x0.01p0 has scaleFactorCompensation == +3 >+ scaleFactor -= scaleFactorCompensation; >+ } >+ } >+ >+ int e = (exponentSign * exponent) + scaleFactor; >+ if (e - 1 > MAX_SINGLE_EXPONENT) { >+ // overflow to +infinity >+ result = Float.floatToIntBits(Float.POSITIVE_INFINITY); >+ } else if (e - 1 >= MIN_NORMALIZED_SINGLE_EXPONENT) { >+ // can be represented as a normalized single >+ // the left most bit must be discarded (it's always a 1) >+ long biasedExponent = e - 1 + SINGLE_EXPONENT_BIAS; >+ result = fraction & ~(1L << SINGLE_FRACTION_WIDTH); >+ result |= (biasedExponent << SINGLE_EXPONENT_SHIFT); >+ } else if (e - 1 > MIN_UNNORMALIZED_SINGLE_EXPONENT) { >+ // can be represented as an unnormalized single >+ long biasedExponent = 0; >+ result = fraction >>> (MIN_NORMALIZED_SINGLE_EXPONENT - e + 1); >+ result |= (biasedExponent << SINGLE_EXPONENT_SHIFT); >+ } else { >+ // underflow - return Float.NaN >+ result = Float.floatToIntBits(Float.NaN); >+ } >+ return result; >+ } >+}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 74126
:
14584
|
14586
| 14808 |
14809