obligated to do so. If you do not wish to do so, delete this
exception statement from your version. */
-
/**
- * Instances of class <code>Float</code> represent primitive
- * <code>float</code> values.
- *
+ * Instances of class <code>Float</code> represent primitive <code>float</code>
+ * values.
+ *
* Additionally, this class provides various helper functions and variables
* related to floats.
- *
+ *
* @author Paul Fisher
* @author Andrew Haley (aph@cygnus.com)
* @author Eric Blake (ebb9@email.byu.edu)
* @since 1.0
* @status partly updated to 1.5
*/
-public final class Float
-{
+public final class Float {
/**
* Compatible with JDK 1.0+.
*/
private static final long serialVersionUID = -2671257302660747028L;
/**
- * The maximum positive value a <code>double</code> may represent
- * is 3.4028235e+38f.
+ * The maximum positive value a <code>double</code> may represent is
+ * 3.4028235e+38f.
*/
public static final float MAX_VALUE = 3.4028235e+38f;
/**
- * The minimum positive value a <code>float</code> may represent
- * is 1.4e-45.
+ * The minimum positive value a <code>float</code> may represent is 1.4e-45.
*/
public static final float MIN_VALUE = 1.4e-45f;
/**
* The primitive type <code>float</code> is represented by this
* <code>Class</code> object.
+ *
* @since 1.1
*/
- //public static final Class<Float> TYPE = (Class<Float>) VMClassLoader.getPrimitiveClass('F');
+ // public static final Class<Float> TYPE = (Class<Float>)
+ // VMClassLoader.getPrimitiveClass('F');
/**
* The number of bits needed to represent a <code>float</code>.
+ *
* @since 1.5
*/
public static final int SIZE = 32;
/**
* The immutable value of this Float.
- *
+ *
* @serial the wrapped float
*/
private final float value;
/**
* Create a <code>Float</code> from the primitive <code>float</code>
* specified.
- *
- * @param value the <code>float</code> argument
+ *
+ * @param value
+ * the <code>float</code> argument
*/
- public Float(float value)
- {
+ public Float(float value) {
this.value = value;
}
/**
* Create a <code>Float</code> from the primitive <code>double</code>
* specified.
- *
- * @param value the <code>double</code> argument
+ *
+ * @param value
+ * the <code>double</code> argument
*/
- public Float(double value)
- {
+ public Float(double value) {
this.value = (float) value;
}
/**
- * Create a <code>Float</code> from the specified <code>String</code>.
- * This method calls <code>Float.parseFloat()</code>.
- *
- * @param s the <code>String</code> to convert
- * @throws NumberFormatException if <code>s</code> cannot be parsed as a
- * <code>float</code>
- * @throws NullPointerException if <code>s</code> is null
+ * Create a <code>Float</code> from the specified <code>String</code>. This
+ * method calls <code>Float.parseFloat()</code>.
+ *
+ * @param s
+ * the <code>String</code> to convert
+ * @throws NumberFormatException
+ * if <code>s</code> cannot be parsed as a <code>float</code>
+ * @throws NullPointerException
+ * if <code>s</code> is null
* @see #parseFloat(String)
*/
- public Float(String s)
- {
+ public Float(String s) {
value = parseFloat(s);
}
/**
- * Convert the <code>float</code> to a <code>String</code>.
- * Floating-point string representation is fairly complex: here is a
- * rundown of the possible values. "<code>[-]</code>" indicates that a
- * negative sign will be printed if the value (or exponent) is negative.
- * "<code><number></code>" means a string of digits ('0' to '9').
- * "<code><digit></code>" means a single digit ('0' to '9').<br>
- *
+ * Convert the <code>float</code> to a <code>String</code>. Floating-point
+ * string representation is fairly complex: here is a rundown of the possible
+ * values. "<code>[-]</code>" indicates that a negative sign will be printed
+ * if the value (or exponent) is negative. "<code><number></code>" means
+ * a string of digits ('0' to '9'). "<code><digit></code>" means a
+ * single digit ('0' to '9').<br>
+ *
* <table border=1>
- * <tr><th>Value of Float</th><th>String Representation</th></tr>
- * <tr><td>[+-] 0</td> <td><code>[-]0.0</code></td></tr>
- * <tr><td>Between [+-] 10<sup>-3</sup> and 10<sup>7</sup>, exclusive</td>
- * <td><code>[-]number.number</code></td></tr>
- * <tr><td>Other numeric value</td>
- * <td><code>[-]<digit>.<number>
- * E[-]<number></code></td></tr>
- * <tr><td>[+-] infinity</td> <td><code>[-]Infinity</code></td></tr>
- * <tr><td>NaN</td> <td><code>NaN</code></td></tr>
+ * <tr>
+ * <th>Value of Float</th>
+ * <th>String Representation</th>
+ * </tr>
+ * <tr>
+ * <td>[+-] 0</td>
+ * <td><code>[-]0.0</code></td>
+ * </tr>
+ * <tr>
+ * <td>Between [+-] 10<sup>-3</sup> and 10<sup>7</sup>, exclusive</td>
+ * <td><code>[-]number.number</code></td>
+ * </tr>
+ * <tr>
+ * <td>Other numeric value</td>
+ * <td><code>[-]<digit>.<number>
+ * E[-]<number></code></td>
+ * </tr>
+ * <tr>
+ * <td>[+-] infinity</td>
+ * <td><code>[-]Infinity</code></td>
+ * </tr>
+ * <tr>
+ * <td>NaN</td>
+ * <td><code>NaN</code></td>
+ * </tr>
* </table>
- *
- * Yes, negative zero <em>is</em> a possible value. Note that there is
- * <em>always</em> a <code>.</code> and at least one digit printed after
- * it: even if the number is 3, it will be printed as <code>3.0</code>.
- * After the ".", all digits will be printed except trailing zeros. The
- * result is rounded to the shortest decimal number which will parse back
- * to the same float.
- *
- * <p>To create other output formats, use {@link java.text.NumberFormat}.
- *
+ *
+ * Yes, negative zero <em>is</em> a possible value. Note that there is
+ * <em>always</em> a <code>.</code> and at least one digit printed after it:
+ * even if the number is 3, it will be printed as <code>3.0</code>. After the
+ * ".", all digits will be printed except trailing zeros. The result is
+ * rounded to the shortest decimal number which will parse back to the same
+ * float.
+ *
+ * <p>
+ * To create other output formats, use {@link java.text.NumberFormat}.
+ *
* @XXX specify where we are not in accord with the spec.
- *
- * @param f the <code>float</code> to convert
+ *
+ * @param f
+ * the <code>float</code> to convert
* @return the <code>String</code> representing the <code>float</code>
*/
- /*public static String toString(float f)
- {
- return VMFloat.toString(f);
- }*/
+ /*
+ * public static String toString(float f) { return VMFloat.toString(f); }
+ */
/**
- * Convert a float value to a hexadecimal string. This converts as
- * follows:
+ * 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.
+ * <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
+ *
+ * @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);
- CPStringBuilder result = new CPStringBuilder();
-
- 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();
- }*/
+ /*
+ * public static String toHexString(float f) { if (isNaN(f)) return "NaN"; if
+ * (isInfinite(f)) return f < 0 ? "-Infinity" : "Infinity";
+ *
+ * int bits = floatToIntBits(f); CPStringBuilder result = new
+ * CPStringBuilder();
+ *
+ * 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
+ *
+ * @param s
+ * the <code>String</code> to convert
* @return the new <code>Float</code>
- * @throws NumberFormatException if <code>s</code> cannot be parsed as a
- * <code>float</code>
- * @throws NullPointerException if <code>s</code> is null
+ * @throws NumberFormatException
+ * if <code>s</code> cannot be parsed as a <code>float</code>
+ * @throws NullPointerException
+ * if <code>s</code> is null
* @see #parseFloat(String)
*/
- public static Float valueOf(String s)
- {
+ public static Float valueOf(String s) {
return valueOf(parseFloat(s));
}
/**
- * Returns a <code>Float</code> object wrapping the value.
- * In contrast to the <code>Float</code> constructor, this method
- * may cache some values. It is used by boxing conversion.
- *
- * @param val the value to wrap
+ * Returns a <code>Float</code> object wrapping the value. In contrast to the
+ * <code>Float</code> constructor, this method may cache some values. It is
+ * used by boxing conversion.
+ *
+ * @param val
+ * the value to wrap
* @return the <code>Float</code>
* @since 1.5
*/
- public static Float valueOf(float val)
- {
- if ((val == 0.0)/* && (floatToRawIntBits(val) == 0)*/)
+ public static Float valueOf(float val) {
+ if ((val == 0.0)/* && (floatToRawIntBits(val) == 0) */)
return ZERO;
else if (val == 1.0)
return ONE;
/**
* Parse the specified <code>String</code> as a <code>float</code>. The
* extended BNF grammar is as follows:<br>
+ *
* <pre>
* <em>DecodableString</em>:
* ( [ <code>-</code> | <code>+</code> ] <code>NaN</code> )
* [ <code>-</code> | <code>+</code> ] { <em>Digit</em> }+ )
* <em>Digit</em>: <em><code>'0'</code> through <code>'9'</code></em>
* </pre>
- *
- * <p>NaN and infinity are special cases, to allow parsing of the output
- * of toString. Otherwise, the result is determined by calculating
- * <em>n * 10<sup>exponent</sup></em> to infinite precision, then rounding
- * to the nearest float. Remember that many numbers cannot be precisely
- * represented in floating point. In case of overflow, infinity is used,
- * and in case of underflow, signed zero is used. Unlike Integer.parseInt,
- * this does not accept Unicode digits outside the ASCII range.
- *
- * <p>If an unexpected character is found in the <code>String</code>, a
- * <code>NumberFormatException</code> will be thrown. Leading and trailing
- * 'whitespace' is ignored via <code>String.trim()</code>, but spaces
- * internal to the actual number are not allowed.
- *
- * <p>To parse numbers according to another format, consider using
+ *
+ * <p>
+ * NaN and infinity are special cases, to allow parsing of the output of
+ * toString. Otherwise, the result is determined by calculating
+ * <em>n * 10<sup>exponent</sup></em> to infinite precision, then rounding to
+ * the nearest float. Remember that many numbers cannot be precisely
+ * represented in floating point. In case of overflow, infinity is used, and
+ * in case of underflow, signed zero is used. Unlike Integer.parseInt, this
+ * does not accept Unicode digits outside the ASCII range.
+ *
+ * <p>
+ * If an unexpected character is found in the <code>String</code>, a
+ * <code>NumberFormatException</code> will be thrown. Leading and trailing
+ * 'whitespace' is ignored via <code>String.trim()</code>, but spaces internal
+ * to the actual number are not allowed.
+ *
+ * <p>
+ * To parse numbers according to another format, consider using
* {@link java.text.NumberFormat}.
- *
+ *
* @XXX specify where/how we are not in accord with the spec.
- *
- * @param str the <code>String</code> to convert
+ *
+ * @param str
+ * the <code>String</code> to convert
* @return the <code>float</code> value of <code>s</code>
- * @throws NumberFormatException if <code>str</code> cannot be parsed as a
- * <code>float</code>
- * @throws NullPointerException if <code>str</code> is null
+ * @throws NumberFormatException
+ * if <code>str</code> cannot be parsed as a <code>float</code>
+ * @throws NullPointerException
+ * if <code>str</code> is null
* @see #MIN_VALUE
* @see #MAX_VALUE
* @see #POSITIVE_INFINITY
* @see #NEGATIVE_INFINITY
* @since 1.2
*/
- public static float parseFloat(String str)
- {
- //return VMFloat.parseFloat(str);
- return (float)(Double.parseDouble(str));
+ public static float parseFloat(String str) {
+ // return VMFloat.parseFloat(str);
+ return (float) (Double.parseDouble(str));
}
/**
- * Return <code>true</code> if the <code>float</code> has the same
- * value as <code>NaN</code>, otherwise return <code>false</code>.
- *
- * @param v the <code>float</code> to compare
+ * Return <code>true</code> if the <code>float</code> has the same value as
+ * <code>NaN</code>, otherwise return <code>false</code>.
+ *
+ * @param v
+ * the <code>float</code> to compare
* @return whether the argument is <code>NaN</code>
*/
- public static boolean isNaN(float v)
- {
+ public static boolean isNaN(float v) {
// This works since NaN != NaN is the only reflexive inequality
// comparison which returns true.
return v != v;
}
/**
- * Return <code>true</code> if the <code>float</code> has a value
- * equal to either <code>NEGATIVE_INFINITY</code> or
- * <code>POSITIVE_INFINITY</code>, otherwise return <code>false</code>.
- *
- * @param v the <code>float</code> to compare
+ * Return <code>true</code> if the <code>float</code> has a value equal to
+ * either <code>NEGATIVE_INFINITY</code> or <code>POSITIVE_INFINITY</code>,
+ * otherwise return <code>false</code>.
+ *
+ * @param v
+ * the <code>float</code> to compare
* @return whether the argument is (-/+) infinity
*/
- public static boolean isInfinite(float v)
- {
+ public static boolean isInfinite(float v) {
return v == POSITIVE_INFINITY || v == NEGATIVE_INFINITY;
}
/**
- * Return <code>true</code> if the value of this <code>Float</code>
- * is the same as <code>NaN</code>, otherwise return <code>false</code>.
- *
+ * Return <code>true</code> if the value of this <code>Float</code> is the
+ * same as <code>NaN</code>, otherwise return <code>false</code>.
+ *
* @return whether this <code>Float</code> is <code>NaN</code>
*/
- public boolean isNaN()
- {
+ public boolean isNaN() {
return isNaN(value);
}
/**
- * Return <code>true</code> if the value of this <code>Float</code>
- * is the same as <code>NEGATIVE_INFINITY</code> or
- * <code>POSITIVE_INFINITY</code>, otherwise return <code>false</code>.
- *
+ * Return <code>true</code> if the value of this <code>Float</code> is the
+ * same as <code>NEGATIVE_INFINITY</code> or <code>POSITIVE_INFINITY</code>,
+ * otherwise return <code>false</code>.
+ *
* @return whether this <code>Float</code> is (-/+) infinity
*/
- public boolean isInfinite()
- {
+ public boolean isInfinite() {
return isInfinite(value);
}
/**
- * Convert the <code>float</code> value of this <code>Float</code>
- * to a <code>String</code>. This method calls
- * <code>Float.toString(float)</code> to do its dirty work.
- *
+ * Convert the <code>float</code> value of this <code>Float</code> to a
+ * <code>String</code>. This method calls <code>Float.toString(float)</code>
+ * to do its dirty work.
+ *
* @return the <code>String</code> representation
* @see #toString(float)
*/
- /*public String toString()
- {
- return toString(value);
- }*/
+ /*
+ * public String toString() { return toString(value); }
+ */
/**
* Return the value of this <code>Float</code> as a <code>byte</code>.
- *
+ *
* @return the byte value
* @since 1.1
*/
- public byte byteValue()
- {
+ public byte byteValue() {
return (byte) value;
}
/**
* Return the value of this <code>Float</code> as a <code>short</code>.
- *
+ *
* @return the short value
* @since 1.1
*/
- public short shortValue()
- {
+ public short shortValue() {
return (short) value;
}
/**
* Return the value of this <code>Integer</code> as an <code>int</code>.
- *
+ *
* @return the int value
*/
- public int intValue()
- {
+ public int intValue() {
return (int) value;
}
/**
* Return the value of this <code>Integer</code> as a <code>long</code>.
- *
+ *
* @return the long value
*/
- public long longValue()
- {
+ public long longValue() {
return (long) value;
}
/**
* Return the value of this <code>Float</code>.
- *
+ *
* @return the float value
*/
- public float floatValue()
- {
+ public float floatValue() {
return value;
}
/**
* Return the value of this <code>Float</code> as a <code>double</code>
- *
+ *
* @return the double value
*/
- public double doubleValue()
- {
+ public double doubleValue() {
return value;
}
/**
- * Return a hashcode representing this Object. <code>Float</code>'s hash
- * code is calculated by calling <code>floatToIntBits(floatValue())</code>.
- *
+ * Return a hashcode representing this Object. <code>Float</code>'s hash code
+ * is calculated by calling <code>floatToIntBits(floatValue())</code>.
+ *
* @return this Object's hash code
* @see #floatToIntBits(float)
*/
- /*public int hashCode()
- {
- return floatToIntBits(value);
- }*/
+ /*
+ * public int hashCode() { return floatToIntBits(value); }
+ */
/**
* Returns <code>true</code> if <code>obj</code> is an instance of
* two floats with <code>==</code>, this treats two instances of
* <code>Float.NaN</code> as equal, but treats <code>0.0</code> and
* <code>-0.0</code> as unequal.
- *
- * <p>Note that <code>f1.equals(f2)</code> is identical to
+ *
+ * <p>
+ * Note that <code>f1.equals(f2)</code> is identical to
* <code>floatToIntBits(f1.floatValue()) ==
* floatToIntBits(f2.floatValue())</code>.
- *
- * @param obj the object to compare
+ *
+ * @param obj
+ * the object to compare
* @return whether the objects are semantically equal
*/
- /*public boolean equals(Object obj)
- {
- if (obj instanceof Float)
- {
- float f = ((Float) obj).value;
- return (floatToRawIntBits(value) == floatToRawIntBits(f)) ||
- (isNaN(value) && isNaN(f));
- }
- return false;
- }*/
+ /*
+ * public boolean equals(Object obj) { if (obj instanceof Float) { float f =
+ * ((Float) obj).value; return (floatToRawIntBits(value) ==
+ * floatToRawIntBits(f)) || (isNaN(value) && isNaN(f)); } return false; }
+ */
/**
* Convert the float to the IEEE 754 floating-point "single format" bit
- * layout. Bit 31 (the most significant) is the sign bit, bits 30-23
- * (masked by 0x7f800000) represent the exponent, and bits 22-0
- * (masked by 0x007fffff) are the mantissa. This function collapses all
- * versions of NaN to 0x7fc00000. The result of this function can be used
- * as the argument to <code>Float.intBitsToFloat(int)</code> to obtain the
- * original <code>float</code> value.
- *
- * @param value the <code>float</code> to convert
+ * layout. Bit 31 (the most significant) is the sign bit, bits 30-23 (masked
+ * by 0x7f800000) represent the exponent, and bits 22-0 (masked by 0x007fffff)
+ * are the mantissa. This function collapses all versions of NaN to
+ * 0x7fc00000. The result of this function can be used as the argument to
+ * <code>Float.intBitsToFloat(int)</code> to obtain the original
+ * <code>float</code> value.
+ *
+ * @param value
+ * the <code>float</code> to convert
* @return the bits of the <code>float</code>
* @see #intBitsToFloat(int)
*/
- /*public static int floatToIntBits(float value)
- {
- if (isNaN(value))
- return 0x7fc00000;
- else
- return VMFloat.floatToRawIntBits(value);
- }*/
+ /*
+ * public static int floatToIntBits(float value) { if (isNaN(value)) return
+ * 0x7fc00000; else return VMFloat.floatToRawIntBits(value); }
+ */
/**
* Convert the float to the IEEE 754 floating-point "single format" bit
- * layout. Bit 31 (the most significant) is the sign bit, bits 30-23
- * (masked by 0x7f800000) represent the exponent, and bits 22-0
- * (masked by 0x007fffff) are the mantissa. This function leaves NaN alone,
- * rather than collapsing to a canonical value. The result of this function
- * can be used as the argument to <code>Float.intBitsToFloat(int)</code> to
- * obtain the original <code>float</code> value.
- *
- * @param value the <code>float</code> to convert
+ * layout. Bit 31 (the most significant) is the sign bit, bits 30-23 (masked
+ * by 0x7f800000) represent the exponent, and bits 22-0 (masked by 0x007fffff)
+ * are the mantissa. This function leaves NaN alone, rather than collapsing to
+ * a canonical value. The result of this function can be used as the argument
+ * to <code>Float.intBitsToFloat(int)</code> to obtain the original
+ * <code>float</code> value.
+ *
+ * @param value
+ * the <code>float</code> to convert
* @return the bits of the <code>float</code>
* @see #intBitsToFloat(int)
*/
- /*public static int floatToRawIntBits(float value)
- {
- return VMFloat.floatToRawIntBits(value);
- }*/
+ /*
+ * public static int floatToRawIntBits(float value) { return
+ * VMFloat.floatToRawIntBits(value); }
+ */
/**
- * Convert the argument in IEEE 754 floating-point "single format" bit
- * layout to the corresponding float. Bit 31 (the most significant) is the
- * sign bit, bits 30-23 (masked by 0x7f800000) represent the exponent, and
- * bits 22-0 (masked by 0x007fffff) are the mantissa. This function leaves
- * NaN alone, so that you can recover the bit pattern with
+ * Convert the argument in IEEE 754 floating-point "single format" bit layout
+ * to the corresponding float. Bit 31 (the most significant) is the sign bit,
+ * bits 30-23 (masked by 0x7f800000) represent the exponent, and bits 22-0
+ * (masked by 0x007fffff) are the mantissa. This function leaves NaN alone, so
+ * that you can recover the bit pattern with
* <code>Float.floatToRawIntBits(float)</code>.
- *
- * @param bits the bits to convert
+ *
+ * @param bits
+ * the bits to convert
* @return the <code>float</code> represented by the bits
* @see #floatToIntBits(float)
* @see #floatToRawIntBits(float)
*/
- /*public static float intBitsToFloat(int bits)
- {
- return VMFloat.intBitsToFloat(bits);
- }*/
+ /*
+ * public static float intBitsToFloat(int bits) { return
+ * VMFloat.intBitsToFloat(bits); }
+ */
/**
* Compare two Floats numerically by comparing their <code>float</code>
* values. The result is positive if the first is greater, negative if the
- * second is greater, and 0 if the two are equal. However, this special
- * cases NaN and signed zero as follows: NaN is considered greater than
- * all other floats, including <code>POSITIVE_INFINITY</code>, and positive
- * zero is considered greater than negative zero.
- *
- * @param f the Float to compare
+ * second is greater, and 0 if the two are equal. However, this special cases
+ * NaN and signed zero as follows: NaN is considered greater than all other
+ * floats, including <code>POSITIVE_INFINITY</code>, and positive zero is
+ * considered greater than negative zero.
+ *
+ * @param f
+ * the Float to compare
* @return the comparison
* @since 1.2
*/
- /*public int compareTo(Float f)
- {
- return compare(value, f.value);
- }*/
+ /*
+ * public int compareTo(Float f) { return compare(value, f.value); }
+ */
/**
- * Behaves like <code>new Float(x).compareTo(new Float(y))</code>; in
- * other words this compares two floats, special casing NaN and zero,
- * without the overhead of objects.
- *
- * @param x the first float to compare
- * @param y the second float to compare
+ * Behaves like <code>new Float(x).compareTo(new Float(y))</code>; in other
+ * words this compares two floats, special casing NaN and zero, without the
+ * overhead of objects.
+ *
+ * @param x
+ * the first float to compare
+ * @param y
+ * the second float to compare
* @return the comparison
* @since 1.4
*/
- /*public static int compare(float x, float y)
- {
- // handle the easy cases:
- if (x < y)
- return -1;
- if (x > y)
- return 1;
-
- // handle equality respecting that 0.0 != -0.0 (hence not using x == y):
- int ix = floatToRawIntBits(x);
- int iy = floatToRawIntBits(y);
- if (ix == iy)
- return 0;
-
- // handle NaNs:
- if (x != x)
- return (y != y) ? 0 : 1;
- else if (y != y)
- return -1;
-
- // handle +/- 0.0
- return (ix < iy) ? -1 : 1;
- }*/
+ /*
+ * public static int compare(float x, float y) { // handle the easy cases: if
+ * (x < y) return -1; if (x > y) return 1;
+ *
+ * // handle equality respecting that 0.0 != -0.0 (hence not using x == y):
+ * int ix = floatToRawIntBits(x); int iy = floatToRawIntBits(y); if (ix == iy)
+ * return 0;
+ *
+ * // handle NaNs: if (x != x) return (y != y) ? 0 : 1; else if (y != y)
+ * return -1;
+ *
+ * // handle +/- 0.0 return (ix < iy) ? -1 : 1; }
+ */
}
package IR.Flat;
+
import IR.*;
import IR.Tree.*;
import Util.*;
-
public class BCXSSJavaInjectError implements BuildCodeExtension {
private State state;
private BuildCode buildCode;
- private String nStr = "__ssjava_inv_error_prob__";
+ private String nStr = "__ssjava_inv_error_prob__";
private String errorInjectedStr = "__ssjava_error_has_been_injected__";
+ private String errorInjectionStarted = "__ssjava_error_injection_started__";
+ private boolean agg = false;
- public BCXSSJavaInjectError( State state, BuildCode buildCode ) {
- this.state = state;
+ public BCXSSJavaInjectError(State state, BuildCode buildCode) {
+ this.state = state;
this.buildCode = buildCode;
}
- public void additionalIncludesMethodsImplementation( PrintWriter outmethod ) {
+ public void additionalIncludesMethodsImplementation(PrintWriter outmethod) {
outmethod.println("#include <stdlib.h>");
outmethod.println("#include <stdio.h>");
}
- // the reason for errorInjectionInit is that some code (like static initializers
- // in the compiled program) actually run before the GENERATED MAIN runs! Not the
- // complied program's main, either! So just rig it so no error injection code runs
+ // the reason for errorInjectionInit is that some code (like static
+ // initializers
+ // in the compiled program) actually run before the GENERATED MAIN runs! Not
+ // the
+ // complied program's main, either! So just rig it so no error injection code
+ // runs
// until we're sure the random seed is initialized.
- public void additionalCodeGen( PrintWriter outmethodheader,
- PrintWriter outstructs,
- PrintWriter outmethod ) {
- outmethodheader.println("extern int "+nStr+";");
- outmethodheader.println("extern int "+errorInjectedStr+";");
+ public void additionalCodeGen(PrintWriter outmethodheader, PrintWriter outstructs,
+ PrintWriter outmethod) {
+ outmethodheader.println("extern int " + nStr + ";");
+ outmethodheader.println("extern int " + errorInjectedStr + ";");
outmethodheader.println("extern int errorInjectionInit;");
+ outmethodheader.println("extern int " + errorInjectionStarted + ";");
+ outmethodheader.println("extern int errorInjectionMax;");
- outmethod.println("int "+nStr+" = "+state.SSJAVA_INV_ERROR_PROB+";");
- outmethod.println("int "+errorInjectedStr+" = 0;");
+ outmethod.println("int " + nStr + " = " + state.SSJAVA_INV_ERROR_PROB + ";");
+ outmethod.println("int " + errorInjectedStr + " = 0;");
+ outmethod.println("int " + errorInjectionStarted + " = 0;");
+ outmethod.println("int errorInjectionMax = 1;");
outmethod.println("int errorInjectionInit = 0;");
}
- public void additionalCodeAtTopOfMain( PrintWriter outmethod ) {
- outmethod.println(" srand("+state.SSJAVA_ERROR_SEED+");");
+ public void additionalCodeAtTopOfMain(PrintWriter outmethod) {
+ outmethod.println(" srand(" + state.SSJAVA_ERROR_SEED + ");");
outmethod.println(" errorInjectionInit = 1;");
}
-
- public void additionalCodePostNode( FlatMethod fm, FlatNode fn, PrintWriter output ) {
+
+ public void additionalCodePreNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
+ }
+
+ public void additionalCodePostNode(FlatMethod fm, FlatNode fn, PrintWriter output) {
TempDescriptor injectTarget = null;
-
- switch( fn.kind() ) {
- case FKind.FlatOpNode:
- FlatOpNode fon = (FlatOpNode) fn;
- if( fon.getOp().getOp() == Operation.DIV ) {
- injectTarget = fon.getDest();
- }
- break;
-
- case FKind.FlatFieldNode:
- injectTarget = ((FlatFieldNode) fn).getDst();
- break;
-
- case FKind.FlatElementNode:
- injectTarget = ((FlatElementNode) fn).getDst();
- break;
+ FieldDescriptor injectField = null;
+
+ if ((!state.getAnnotationRequireSet().contains(fm.getMethod()))) {
+ return;
}
- if( injectTarget != null &&
- injectTarget.getType().isPrimitive() &&
- !injectTarget.getType().isArray()
- ) {
- output.println("if( errorInjectionInit ) {");
- output.println(" int roll = rand() % "+nStr+";");
- output.println(" if( !"+errorInjectedStr+" && roll == 0 ) {" );
- output.println(" "+errorInjectedStr+" = 1;" );
-
- // inject a random value
- output.println(" "+buildCode.generateTemp( fm, injectTarget )+
- " = ("+injectTarget.getType().getSafeSymbol()+") rand();" );
-
- output.println(" printf(\"SSJAVA: Injecting error at file:%s, func:%s, line:%d \\n\"" +
- ", __FILE__, __func__, __LINE__);");
- output.println(" }" );
- output.println("}");
+ if (fm.getMethod().getClassDesc().getClassName().equals("String")) {
+ return;
}
+
+ switch (fn.kind()) {
+ case FKind.FlatOpNode:
+ FlatOpNode fon = (FlatOpNode) fn;
+ injectTarget = fon.getDest();
+
+ int op = fon.getOp().getOp();
+ if (injectTarget.getType().isPrimitive()
+ && (op == Operation.DIV || (agg && (op == Operation.ADD || op == Operation.SUB
+ || op == Operation.MULT || op == Operation.MOD || op == Operation.LOGIC_AND
+ || op == Operation.LOGIC_OR || op == Operation.LOGIC_NOT || op == Operation.NOTEQUAL
+ || op == Operation.BIT_AND || op == Operation.BIT_OR || op == Operation.BIT_XOR/*|| op == Operation.EQUAL*/)))) {
+ // inject a random value
+ initializeInjection(output);
+ output.println(" " + buildCode.generateTemp(fm, injectTarget) + " = ("
+ + injectTarget.getType().getSafeSymbol() + ") rand();");
+ closingInjection(output);
+ }
+ break;
+
+ // case FKind.FlatFieldNode:
+ // injectTarget = ((FlatFieldNode) fn).getDst();
+ // break;
+ //
+ // case FKind.FlatElementNode:
+ // injectTarget = ((FlatElementNode) fn).getDst();
+ // break;
+
+ case FKind.FlatSetFieldNode:
+ FlatSetFieldNode fsn = (FlatSetFieldNode) fn;
+ injectTarget = fsn.getDst();
+ injectField = fsn.getField();
+
+ if (injectTarget != null && injectField != null && injectField.getType().isPrimitive()
+ && !injectTarget.getType().isArray() && !injectField.isStatic()) {
+ initializeInjection(output);
+ // inject a random value
+ output.println(" " + buildCode.generateTemp(fm, injectTarget) + "->"
+ + injectField.getSafeSymbol() + " = (" + injectField.getType().getSafeSymbol()
+ + ") rand();");
+ closingInjection(output);
+
+ }
+
+ break;
+
+ case FKind.FlatSetElementNode:
+ FlatSetElementNode fsen = (FlatSetElementNode) fn;
+ injectTarget = fsen.getDst();
+
+ if (injectTarget != null && injectTarget.getType().isPrimitive()) {
+ initializeInjection(output);
+
+ String type;
+ TypeDescriptor elementtype = fsen.getDst().getType().dereference();
+ if (elementtype.isClass() && elementtype.getClassDesc().isEnum()) {
+ type = "int ";
+ } else if (elementtype.isArray() || elementtype.isClass() || (elementtype.isNull()))
+ type = "void *";
+ else
+ type = elementtype.getSafeSymbol() + " ";
+
+ output.println("((" + type + "*)(((char *) &(" + buildCode.generateTemp(fm, injectTarget)
+ + "->___length___))+sizeof(int)))[" + buildCode.generateTemp(fm, fsen.getIndex())
+ + "] = (" + type + ") rand();");
+
+ closingInjection(output);
+ }
+ break;
+
+ }
+
}
+ private void initializeInjection(PrintWriter output) {
+ output.println("if( errorInjectionInit ) {");
+ output.println(" int roll = rand() % " + nStr + ";");
+ output.println(" if( ( " + errorInjectedStr + " && " + errorInjectionStarted
+ + " < errorInjectionMax ) || (!" + errorInjectedStr + " && roll == 0) ) {");
+ output.println(" " + errorInjectedStr + " = 1;");
+ output.println(" " + errorInjectionStarted + " += 1;");
+ }
+ private void closingInjection(PrintWriter output) {
+ output.println(" printf(\"SSJAVA: Injecting error at file:%s, func:%s, line:%d \\n\""
+ + ", __FILE__, __func__, __LINE__);");
+ output.println(" }");
+ output.println("}");
+ }
+
+ public void printExtraArrayFields(PrintWriter outclassdefs) {
+ }
+
+ public void outputTransCode(PrintWriter output) {
+ }
- public void printExtraArrayFields(PrintWriter outclassdefs){}
- public void outputTransCode(PrintWriter output){}
- public void buildCodeSetup(){}
- public void generateSizeArrayExtensions(PrintWriter outclassdefs){}
- public void preCodeGenInitialization(){}
- public void postCodeGenCleanUp(){}
- public void additionalIncludesMethodsHeader(PrintWriter outmethodheader){}
- public void additionalIncludesStructsHeader(PrintWriter outstructs){}
- public void additionalClassObjectFields(PrintWriter outclassdefs){}
- public void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar){}
- public void additionalCodeAtBottomOfMain(PrintWriter outmethod){}
- public void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod){}
- public void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm){}
- public void additionalCodePreNode(FlatMethod fm, FlatNode fn, PrintWriter output){}
- public void additionalCodeNewObject(PrintWriter outmethod, String dstVar, FlatNew flatNew){}
- public void additionalCodeNewStringLiteral(PrintWriter output, String dstVar){}
+ public void buildCodeSetup() {
+ }
+
+ public void generateSizeArrayExtensions(PrintWriter outclassdefs) {
+ }
+
+ public void preCodeGenInitialization() {
+ }
+
+ public void postCodeGenCleanUp() {
+ }
+
+ public void additionalIncludesMethodsHeader(PrintWriter outmethodheader) {
+ }
+
+ public void additionalIncludesStructsHeader(PrintWriter outstructs) {
+ }
+
+ public void additionalClassObjectFields(PrintWriter outclassdefs) {
+ }
+
+ public void additionalCodeForCommandLineArgs(PrintWriter outmethod, String argsVar) {
+ }
+
+ public void additionalCodeAtBottomOfMain(PrintWriter outmethod) {
+ }
+
+ public void additionalCodeAtTopMethodsImplementation(PrintWriter outmethod) {
+ }
+
+ public void additionalCodeAtTopFlatMethodBody(PrintWriter output, FlatMethod fm) {
+ }
+
+ public void additionalCodeNewObject(PrintWriter outmethod, String dstVar, FlatNew flatNew) {
+ }
+
+ public void additionalCodeNewStringLiteral(PrintWriter output, String dstVar) {
+ }
}