Float-Point Representation in Java
The Scientific Notation
There are only two floating-point types in Java: float and double. Before diving into them, let’s talk about the fixed-point numbers.
Actually, the integers which are universally known to us are a type of fixed-point number because their decimal points are always fixed at the last position. Besides, there is another type of fixed-point number: fixed-point decimals which are designed to represent the decimals whose absolute values are less than 1(−1<x<1)-1<x<1)−1<x<1). Although the fixed-point decimals are accurate, their applications are very limited. For instance, they can’t be used in large-scale numerical calculations.
We all know the scientific notation. For instance, the decimal 456.789, we can represent it by 4.56789×1024.56789\times10^24.56789×102. This representation is very regular, and is very convenient to work with. Although it’s a decimal calculation, we got an inspiration that scientific notation is more efficient than fixed-point representation.
We can represent any decimals in this formula:
N=M×RE N = M \times R^E N=M×RE
- N: The number you desired to represent;
- M: Mantissa, i.e. the available parts of a number(4.56789 in previous example);
- R: Radix, 10 in decimal, 2 in binary;
- E: Exponent, the times of multiplying.
The Representation of floating-point numbers in computers
Floating-point numbers are represented in scientific notation in computers. Radix is always 2 in computers. All problems we need to consider are mantissa and exponent.
There is a key issue: the binary decimal 1.11 (i.e. 1.75 in decimal), which of the following representations would it be: 1.11×201.11 \times 2^01.11×20 or 0.111×210.111 \times 2^10.111×21?
According to IEEE 754 standard, all binary floating-point numbers must be represented in the form of 1.XXX…1.XXX\dots1.XXX… unless its mantissa is 0. Although the form of 0.XXX…0.XXX\dots0.XXX… seems simplier in calculation than others in some conditions, the form of 1.XXX…1.XXX\dots1.XXX… is mandatory. Because all the integer parts of mantissas are 1, the integer parts are ignored. The reason is that the unique representation can be ensured and this form saved 1-bit accuracy.
After explaining the mantissa, let’s discuss the exponent.
The Representation of Exponent: Offset Code
The exponents of floating-point numbers are represented by offset code.
What is Offset Code?
This is a trick invented by clever people to help comparing numbers in hardwares. In simple terms, Adding a fixed offset to all numbers, so that all negative numbers are turned into positive numbers.In parallel, the minimum negative number is turned into 0.
There are the steps of byte comparing:
- The range of bytes is [−128,127][-128, 127][−128,127];
- By adding 128 to them, the range is [0,255][0, 255][0,255];
- Advantage is that they will be all treated as non-negative numbers in comparing when they are compared in machine. This idea is very efficient.
Tips
- Exponent of float is 8-bit, its bias is 127(27−12^7-127−1).
- Exponent of double is 11-bit, its bias is 1023(210−12^{10}-1210−1).
Why the Range of float Is Wider Than long?
The Range of long
long is a 64-bit type of integer, the first bit is its sign, remaining 63 bits is two’s complement. It’s range is [−263,263−1]≈[−9.2×1018,9.2×1018][-2^{63}, 2^{63}-1] \approx [−9.2×10^{18} ,9.2×10^{18}][−263,263−1]≈[−9.2×1018,9.2×1018].
The Range of float
float is a 32-bit type of floating point number, consists of 3 parts:
- 1 bit of sign;
- 8 bits of exponent(bias is 127, actual range is [−126,127][-126, 127][−126,127]);
- 23 bits of mantissa(actual 24 bits for the sake of integer part is always 1).
The maximum of float is that:
- Mantissa: 1.11111⋯≈21.11111\dots\approx21.11111⋯≈2;
- Exponent: 21272^{127}2127;
- Value: v≈2×2127=2128≈3.4×1038v \approx 2\times2^{127} = 2^{128} \approx3.4\times 10^{38}v≈2×2127=2128≈3.4×1038.
Conclusion: Although float has only 32 bits and long has 64 bits, float takes the advantage of exponential explosion to gain more range in cost of less accuracy.
Hexadecimal Literal Numbers
The binary representation is very long in coding. Hexadecimal representation is a better choice which replace every 4 bits with a hexadecimal character.
Hexadecimal representation starts with 0x or 0X. For example, the Hexadecimal 2012 is 0x7DC.
Good News: Hexadecimal Floating-point Numbers Are Supported in Java
Don’t dive in IEEE 754 standard, just append a p{exponent} or P{exponent} to the mantissa(the radix is 2 rather than 10).
Grammar:0X + Mantissa + P + Exponent
Example:
double d = 0x1.0p3; // equals to 1.0 * 2^3 = 8.0
float f = 0x1.8p2f; // equals to 1.5 * 2^2 = 6.0
更多推荐



所有评论(0)