Question

I am trying to get a good understanding of Java's primitive data types. I already got a good overview and I understand how signed integer values are stored in Java, and how to tell/calculate the range of a byte-, short-, integer- or long-data type.

So, when looking at the Java data type int I know that it is a 32 bit signed value, thus I can tell exactly how many different "states" a int-type can store and what the range of that datatype is (i.e. 2^32 different states, resulting in a range from -2^31 through +(2^31)-1 or roughly -2e+9 through +2e+9).

When looking at the data type float, however, I need some help. I understand that Java's float data type is a 32 bit type (just like int), thus I would assume that it can also store a total of 2^32 different states. However, when I look at the numbers given in this table (http://www.javacamp.org/javaI/primitiveTypes.html) I don't understand how this data type can store floating point numbers in the range from roughly -3e+38 through 3e+38 (which is already a much wider range than what int can cover) PLUS all the single-precision floating point decimals in between - with just 32 bit.

Can any one please explain how floating point numbers are stored and why it "looks like" it can store more information than int within the same number of bits (which feels pretty much impossible to me)? Maybe you can point me to a good read or show me where I made a logical mistake.

Was it helpful?

Solution

The trick is realizing that a float can't accurately hold even all the integers in the range -3e+38 to 3e+38. The difference between "adjacent" float values depends on the magnitude: for float values close to 0, the difference between adjacent values; for very large values (positive or negative) the difference can be very large.

Basically a floating point number consists of:

  • A sign - positive or negative
  • A mantissa or significand (see comments below) - a string of binary digits, effectively
  • An exponent - the number of binary digits to shift the mantissa left or right

The mantissa in a float is 23 bits long, and the exponent is 8 bits - so you'll only ever get 23 (or 24 due to normalization) significant bits of information, but they could be shifted left a lot (to form a huge number) or right a lot (to form a tiny number). There are some other details around normalization which are relevant, but that's the basic idea.

See my .NET-oriented but still Java-relevant article on binary floating point for more information, along with one by Jeffrey Sax.

OTHER TIPS

I'm going to forgo all of the bit-twiddling and upls stuff for simplicity. Let's take a look at a 10-digit number in base 10(unsigned in this case but fairly extensible). It can store numbers from 0 to 9999999999. Now, let's take 2 of those digits and turn them to an exponent, like in floating-point. Now, we can go from 1x10-99 to 99,999,999x10^99. Onbiously a much larger range

Note the fact that at the max we lose our smaller digits. For example, 999,999,999,999,999,991 and 999,999,999,999,999,992 would get truncated down in the same way for the 8 digits that aren't the exponent, since those numbers don't fit in 8 digits. They'd both be 999,999,99x1017

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top