Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

There's a special variable called Double.NaN (and Float.NaN), meaning "Not a Number", which is sometimes returned from math calculations. Once introduced into a math calculation, the result will (usually) be NaN.

Conversions

The Float and Double classes, along with BigDecimal, BigInteger, Integer, Long, Short, and Byte, can all be converted to one another.

...

Code Block
//Integers ('d')
assert String.format('%d', 45) == '45'
assert String.format('%5d,%1$5o', 46L) == '   46,   56'
    //octal format; each minimum 5 chars wide; use an argument twice
assert String.format('%-4d,%<-5x', 47g) == '47  ,2f   '
    //hex format without leading '0x'; left-justified with '-';
    //shortcut ('<') for using argument again
assert String.format('%2d,%<1X', 123) == '123,7B'
    //hex in uppercase with capital 'X'
assert String.format('%04d', 34) == '0034' //zero-pad
assert String.format('%,5d', 12345) == '12,345' //use grouping-separators
assert String.format('%+3d,%2$ 3d', 123L, 456g) == '+123, 456'
    //always use plus sign; always use a leading space
assert String.format('%(3d', -789 as short) == '(789)' //parens for negative
assert String.format('%(3o,%2$(3x,%3$(3X', 123g, 456g, -789g) == '173,1c8,(315)'
    //neg octal/hex only for BigInteger

//Floating-Point ('f', 'a', 'e', 'g')
assert String.format('e = %f', Math.E) == 'e = 2.718282'
    //default 'f' format is 7.6
assert String.format('e=%+6.4f', Math.E) == 'e=+2.7183'
    //precision is digits after decimal point
assert String.format('$ %(,6.2f', -6217.58) == '$ (6,217.58)'
    //'(' flag gives parens, ',' uses separators
assert String.format('%a, %A', 2.7182818f, Math.PI) ==
    '0x1.5bf0a8p1, 0X1.921FB54442D18P1' //'a' for hex
assert String.format('%+010.4a', 23.25d) == '+0x001.7400p4'
    //'+' flag always includes sign; '0' flag zero-fills
assert String.format('%e, %10.4e', Math.E, 12345.6789) ==
    '2.718282e+00, 1.2346e+04' //'e' for scientific format
assert String.format('%(10.5E', -0.0000271) == '(2.71000E-05)'
assert String.format('%g, %10.4G', Math.E, 12345.6789) == '2.71828,  1.235E+04'
    //'f' or 'e', depending on input

Floating-Point Arithmetic

We can perform the same basic operations that integers and BigDecimal can:

...

Code Block
assert (1.23d? true: false)
assert ! (0.0f? true: false)

Bitwise Operations

We can convert a float to the equivalent int bits, or a double to equivalent float bits. For a float, bit 31(mask 0x80000000) is the sign, bits 30-23 (mask 0x7f800000) are the exponent, and bits 22-0 (mask 0x007fffff) are the mantissa. For a double, bit 63 is the sign, bits 62-52 are the exponent, and bits 51-0 are the mantissa.

...

Code Block
assert Float.MAX_VALUE == Float.intBitsToFloat(0x7f7fffff)
assert Float.MIN_NORMAL == Float.intBitsToFloat(0x00800000)
    //the smallest positive nonzero normal value
assert Float.MIN_VALUE == Float.intBitsToFloat(0x1)
    //the smallest positive nonzero value, including subnormal values
assert Float.MAX_EXPONENT == Math.getExponent(Float.MAX_VALUE)
assert Float.MIN_EXPONENT == Math.getExponent(Float.MIN_NORMAL)
assert Float.MIN_EXPONENT == Math.getExponent(Float.MIN_VALUE) + 1
    //for subnormal values

Floating-Point Calculations

There are two constants of type Double, Math.PI and Math.E, that can't be represented exactly, not even as a recurring decimal.

...

Accuracy of the Math methods is measured in terms of such ulps for the worst-case scenario.If a method always has an error less than 0.5 ulps, the method always returns the floating-point number nearest the exact result, and so is always correctly rounded. However, doing this and maintaining floating-point calculation speed together is impractical. Instead, for the Math class, a larger error bound of 1 or 2 ulps is allowed for certain methods. But most methods with more than 0.5 ulp errors are still required to be semi-monotonic, ie, whenever the mathematical function is non-decreasing, so is the floating-point approximation, and vice versa. Not all approximations that have 1 ulp accuracy meet the monotonicity requirements. sin, cos, tan, asin, acos, atan, exp, log, and log10 give results within 1 ulp of the exact result that are semi-monotonic.

Further Calculations

We can find the polar coordinate of two (x,y) coordinates. The result is within 2 ulps of the exact result, and is semi-monotonic.

...