3

In java I am using float to store the numbers. I chose the float format as I am working both with integers and double numbers, where the numbers are different, there can be big integers or big double numbers with different number of decimals. But when I insert these numbers into database, the wrong number is stored. For example:

float value = 0f; value = 67522665; System.out.println(value);

Printed: 6.7522664E7 and it is stored in the database as 67522664 not as 67522665

user1574866
  • 275
  • 2
  • 6
  • 12
  • 3
    Please read http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html "What Every Computer Scientist Should Know About Floating-Point Arithmetic" before doing anything serious involving floating point numbers. – Patashu May 03 '13 at 04:49

3 Answers3

8

Floating point numbers have limited resolution — roughly 7 significant digits. You are seeing round-off error. You can use a double for more resolution or, for exact arithmetic, use BigDecimal.

Suggested reading: What Every Computer Scientist Should Know About Floating-Point Arithmetic

Ted Hopp
  • 232,168
  • 48
  • 399
  • 521
  • 2
    By the way, `BigDecimal` calculation is much slower than other primitive data type. – Drogba May 03 '13 at 04:47
  • 1
    @Drogba - Yes, indeed. But if you need the accuracy, that's the price you need to pay. – Ted Hopp May 03 '13 at 04:48
  • Limited precision, not accuracy. – yshavit May 03 '13 at 04:50
  • 2
    @yshavit - You're right that "accuracy" wasn't the right word. But "precision" isn't right either, since that has to do with repeatability. (IEEE floating point calculations are completely repeatable.) I went with "resolution". – Ted Hopp May 03 '13 at 04:55
  • The problem is the type of the column in the database where I am inserting this value, is float. – user1574866 May 03 '13 at 05:54
  • @TedHopp Precision is a pretty standard term in this regard. It's the one used in [the JLS](http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.2.3), for instance, and the docs for BigDecimal start out with defining it as an "arbitrary precision" number. Heck, it's the term used in the very article you linked to. – yshavit May 03 '13 at 06:30
  • @yshavit - The article I link to in my answer does indeed talk about precision in terms of number of bits. It also talks about "numerical accuracy", "10 digits of accuracy", etc. As far as I can tell, there is no uniformly accepted definition for these terms in computer science. (Lots of definitions, but lots of disagreement.) In terms of real standards, the [International Vocabulary of Metrology](http://www.bipm.org/utils/common/documents/jcgm/JCGM_200_2012.pdf) published by the BIPM has nice definitions for accuracy, precision, and resolution. It's worth a read. – Ted Hopp May 03 '13 at 07:27
1

Doubles and floats have storage issues. How is floating point stored?

"The float and double types are designed primarily for scientific and engineering calculations. They perform binary floating-point arithmetic, which was carefully designed to furnish accurate approximations quickly over a broad range of magnitudes. They do not, however, provide exact results and should not be used where exact results are required."

Don't use float. Use BigDecimal instead. And in my experience with databases, they return their NUMBER-typed elements as BigDecimal. When I fetch them using JDBC, they are BigDecimal objects.

Community
  • 1
  • 1
renz
  • 1,072
  • 3
  • 11
  • 21
0

As far as I got it, this is about the gap size (or ULP, units in the last place) in the binary representation, that is the spacing between contiguous f-point values.

This value is equal to:

2^(e+1-p)

being e the actual exponent of a number, and p the precision.

Note that the spacing (or gap) increases as the value of the represented number increases:

enter image description here

In IEEE-754, the precision is p 24, so you can see that when e >= 23 we can start talking of integer spacing in the floating point world.

2^23 = 8388608   --> 8388608 actually stored IEEE-754
       8388608.2 --> 8388608 actually stored IEEE-754

Things get worse as numbers get bigger. For example:

164415560 --> 164415552 actually stored IEEE-754

Ref: The Spacing of Binary Floating-Point Numbers

Campa
  • 4,267
  • 3
  • 37
  • 42