[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[cp-patches] Patch: FYI: Double.toHexString and Float.toHexString
From: |
Tom Tromey |
Subject: |
[cp-patches] Patch: FYI: Double.toHexString and Float.toHexString |
Date: |
07 Dec 2005 13:09:40 -0700 |
User-agent: |
Gnus/5.09 (Gnus v5.9.0) Emacs/21.3.50 |
I'm checking this in on the trunk.
This adds the new 1.5 methods Double.toHexString and
Float.toHexString. I wrote Mauve tests for both of these. (BTW,
adding a new Mauve test file from Eclipse is super easy... I forgot
how easy it is when all the boilerplate is written for you, even
though I added the templates :-)
The code in both classes is pretty much identical, aside from a few
constants.
Tom
2005-12-07 Tom Tromey <address@hidden>
* java/lang/Float.java (toHexString): New method.
* java/lang/Double.java (toHexString): New method.
Index: java/lang/Double.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/Double.java,v
retrieving revision 1.40
diff -u -r1.40 Double.java
--- java/lang/Double.java 18 Sep 2005 23:00:24 -0000 1.40
+++ java/lang/Double.java 7 Dec 2005 20:08:13 -0000
@@ -173,6 +173,81 @@
}
/**
+ * Convert a double value to a hexadecimal string. This converts as
+ * follows:
+ * <ul>
+ * <li> A NaN value is converted to the string "NaN".
+ * <li> Positive infinity is converted to the string "Infinity".
+ * <li> Negative infinity is converted to the string "-Infinity".
+ * <li> For all other values, the first character of the result is '-'
+ * if the value is negative. This is followed by '0x1.' if the
+ * value is normal, and '0x0.' if the value is denormal. This is
+ * then followed by a (lower-case) hexadecimal representation of the
+ * mantissa, with leading zeros as required for denormal values.
+ * The next character is a 'p', and this is followed by a decimal
+ * representation of the unbiased exponent.
+ * </ul>
+ * @param d the double value
+ * @return the hexadecimal string representation
+ * @since 1.5
+ */
+ public static String toHexString(double d)
+ {
+ if (isNaN(d))
+ return "NaN";
+ if (isInfinite(d))
+ return d < 0 ? "-Infinity" : "Infinity";
+
+ long bits = doubleToLongBits(d);
+ StringBuilder result = new StringBuilder();
+
+ if (bits < 0)
+ result.append('-');
+ result.append("0x");
+
+ final int mantissaBits = 52;
+ final int exponentBits = 11;
+ long mantMask = (1L << mantissaBits) - 1;
+ long mantissa = bits & mantMask;
+ long expMask = (1L << exponentBits) - 1;
+ long exponent = (bits >>> mantissaBits) & expMask;
+
+ result.append(exponent == 0 ? '0' : '1');
+ result.append('.');
+ result.append(Long.toHexString(mantissa));
+ if (exponent == 0 && mantissa != 0)
+ {
+ // Treat denormal specially by inserting '0's to make
+ // the length come out right. The constants here are
+ // to account for things like the '0x'.
+ int offset = 4 + ((bits < 0) ? 1 : 0);
+ // The silly +3 is here to keep the code the same between
+ // the Float and Double cases. In Float the value is
+ // not a multiple of 4.
+ int desiredLength = offset + (mantissaBits + 3) / 4;
+ while (result.length() < desiredLength)
+ result.insert(offset, '0');
+ }
+ result.append('p');
+ if (exponent == 0 && mantissa == 0)
+ {
+ // Zero, so do nothing special.
+ }
+ else
+ {
+ // Apply bias.
+ boolean denormal = exponent == 0;
+ exponent -= (1 << (exponentBits - 1)) - 1;
+ // Handle denormal.
+ if (denormal)
+ ++exponent;
+ }
+
+ result.append(Long.toString(exponent));
+ return result.toString();
+ }
+
+ /**
* Returns a <code>Double</code> object wrapping the value.
* In contrast to the <code>Double</code> constructor, this method
* may cache some values. It is used by boxing conversion.
Index: java/lang/Float.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/Float.java,v
retrieving revision 1.33
diff -u -r1.33 Float.java
--- java/lang/Float.java 18 Sep 2005 23:00:24 -0000 1.33
+++ java/lang/Float.java 7 Dec 2005 20:08:13 -0000
@@ -183,6 +183,83 @@
}
/**
+ * Convert a float value to a hexadecimal string. This converts as
+ * follows:
+ * <ul>
+ * <li> A NaN value is converted to the string "NaN".
+ * <li> Positive infinity is converted to the string "Infinity".
+ * <li> Negative infinity is converted to the string "-Infinity".
+ * <li> For all other values, the first character of the result is '-'
+ * if the value is negative. This is followed by '0x1.' if the
+ * value is normal, and '0x0.' if the value is denormal. This is
+ * then followed by a (lower-case) hexadecimal representation of the
+ * mantissa, with leading zeros as required for denormal values.
+ * The next character is a 'p', and this is followed by a decimal
+ * representation of the unbiased exponent.
+ * </ul>
+ * @param f the float value
+ * @return the hexadecimal string representation
+ * @since 1.5
+ */
+ public static String toHexString(float f)
+ {
+ if (isNaN(f))
+ return "NaN";
+ if (isInfinite(f))
+ return f < 0 ? "-Infinity" : "Infinity";
+
+ int bits = floatToIntBits(f);
+ StringBuilder result = new StringBuilder();
+
+ if (bits < 0)
+ result.append('-');
+ result.append("0x");
+
+ final int mantissaBits = 23;
+ final int exponentBits = 8;
+ int mantMask = (1 << mantissaBits) - 1;
+ int mantissa = bits & mantMask;
+ int expMask = (1 << exponentBits) - 1;
+ int exponent = (bits >>> mantissaBits) & expMask;
+
+ result.append(exponent == 0 ? '0' : '1');
+ result.append('.');
+ // For Float only, we have to adjust the mantissa.
+ mantissa <<= 1;
+ result.append(Integer.toHexString(mantissa));
+ if (exponent == 0 && mantissa != 0)
+ {
+ // Treat denormal specially by inserting '0's to make
+ // the length come out right. The constants here are
+ // to account for things like the '0x'.
+ int offset = 4 + ((bits < 0) ? 1 : 0);
+ // The silly +3 is here to keep the code the same between
+ // the Float and Double cases. In Float the value is
+ // not a multiple of 4.
+ int desiredLength = offset + (mantissaBits + 3) / 4;
+ while (result.length() < desiredLength)
+ result.insert(offset, '0');
+ }
+ result.append('p');
+ if (exponent == 0 && mantissa == 0)
+ {
+ // Zero, so do nothing special.
+ }
+ else
+ {
+ // Apply bias.
+ boolean denormal = exponent == 0;
+ exponent -= (1 << (exponentBits - 1)) - 1;
+ // Handle denormal.
+ if (denormal)
+ ++exponent;
+ }
+
+ result.append(Integer.toString(exponent));
+ return result.toString();
+ }
+
+ /**
* Creates a new <code>Float</code> object using the <code>String</code>.
*
* @param s the <code>String</code> to convert
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [cp-patches] Patch: FYI: Double.toHexString and Float.toHexString,
Tom Tromey <=