user1166635
user1166635

Reputation: 2801

Understanding of a float counter

I have following simple code:

for (float i=0; i<1f; i+=0.1) {
    System.out.println(i);
}

I have just got following results:

0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.70000005
0.8000001
0.9000001

But I can't understand why there is. Please, I hope you can tell me. Thank you.

Upvotes: 1

Views: 848

Answers (4)

Adam
Adam

Reputation: 36703

You almost always need to constrain the number of decimal places when printing floats or doubles.

Java's take on printf from C

for (float i = 0; i < 1f; i += 0.1) {
    System.out.printf("%.1f\n", i);
}

DecimalFormat to print up to 1 decimal place if necessary

DecimalFormat format1 = new DecimalFormat("#.#");
for (float i = 0; i < 1f; i += 0.1) {
    System.out.println(format1.format(i));
}

DecimalFormat to print 1 decimal place always

DecimalFormat format2 = new DecimalFormat("0.0");
for (float i = 0; i < 1f; i += 0.1) {
    System.out.println(format2.format(i));
}

Upvotes: 0

Jan Gr&#228;fen
Jan Gr&#228;fen

Reputation: 314

It's because the way computers store floating point numbers. For detailed information you could have a look at the IEEE 754.

This is related to a numerical problem.

Upvotes: 0

Michael Borgwardt
Michael Borgwardt

Reputation: 346327

From The Floating-Point Guide:

Why don’t my numbers, like 0.1 + 0.2 add up to a nice round 0.3, and instead I get a weird result like 0.30000000000000004?

Because internally, computers use a format (binary floating-point) that cannot accurately represent a number like 0.1, 0.2 or 0.3 at all.

When the code is compiled or interpreted, your “0.1” is already rounded to the nearest number in that format, which results in a small rounding error even before the calculation happens.

Upvotes: 8

Bogdan Emil Mariesan
Bogdan Emil Mariesan

Reputation: 5647

Well because with the way float has been implemented there usually is a very small deviation from the mathematical 0.1f you are incrementing with, so actually you are incrementing with just a small amount over that.

A solution would be to use:

BigDecimal

EDIT:

Michael posted a better description of your problem, but still you should take a look at BigDecimal.

Upvotes: 1

Related Questions