Вопрос по java – Тип данных double или float не корректно вводится в цикле?

1

В цикле я добавляю 0,10, пока не достигну желаемого #, и получаю индекс. Это мой код:

<code>    private static int getIndexOfUnits(float units) {
    int index = -1;
    float addup = 0.10f;
    for(float i = 1.00f; i < units; i=(float)i+addup) {
        index++;
        System.out.println("I = " + i + " Index = " + index);
    }

    return index;
}
</code>

Если количество пройденных единиц составляет 5,7, я вижу:

<code>I = 1.0 Index = 0
I = 1.1 Index = 1
I = 1.2 Index = 2
I = 1.3000001 Index = 3
I = 1.4000001 Index = 4
I = 1.5000001 Index = 5
I = 1.6000001 Index = 6
I = 1.7000002 Index = 7
I = 1.8000002 Index = 8
I = 1.9000002 Index = 9
I = 2.0000002 Index = 10
I = 2.1000001 Index = 11
I = 2.2 Index = 12
I = 2.3 Index = 13
I = 2.3999999 Index = 14
I = 2.4999998 Index = 15
I = 2.5999997 Index = 16
I = 2.6999996 Index = 17
I = 2.7999995 Index = 18
I = 2.8999994 Index = 19
I = 2.9999993 Index = 20
I = 3.0999992 Index = 21
I = 3.199999 Index = 22
I = 3.299999 Index = 23
I = 3.399999 Index = 24
I = 3.4999988 Index = 25
I = 3.5999987 Index = 26
I = 3.6999986 Index = 27
I = 3.7999985 Index = 28
I = 3.8999984 Index = 29
I = 3.9999983 Index = 30
I = 4.0999985 Index = 31
I = 4.1999984 Index = 32
I = 4.2999983 Index = 33
I = 4.399998 Index = 34
I = 4.499998 Index = 35
I = 4.599998 Index = 36
I = 4.699998 Index = 37
I = 4.799998 Index = 38
I = 4.8999977 Index = 39
I = 4.9999976 Index = 40
I = 5.0999975 Index = 41
I = 5.1999974 Index = 42
I = 5.2999973 Index = 43
I = 5.399997 Index = 44
I = 5.499997 Index = 45
I = 5.599997 Index = 46
I = 5.699997 Index = 47
</code>

Если единицы - это большое число, например 18,90 или 29,90, это дает неверный индекс. Индекс обычно на 1 меньше, чем должен быть. Было добавлено только 0.10, но после 2.3 он получает 2.39999 .... при добавлении 0.10 к нему. Я считаю, что это вопрос точности. Как справиться с этим и убедиться, что я получаю правильный индекс на больших # также независимо от использования float или double.

Есть идеи !!!!

Вы понимаете, что 0.10 не имеет точного представления в java (и на любом другом языке) системе с плавающей запятой? Неважно, какую точность вы предоставляете, даже если у java был тип с плавающей запятой с точностью до миллиона битов. Вам нужно использовать специализированный десятичный класс или класс дробей. James K Polk

Ваш Ответ

5   ответов
0

ерация).

Попробуйте вычислить I каждый раз:

I = 1.0f + (i*addup);

И вы не будете накапливать ошибки с плавающей запятой.

12

Гид с плавающей точкой:

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.

Вы не можете использоватьfloat или жеdouble если вам нужны цифры, чтобы сложить точно. использованиеBigDecimal вместо.

1

BigDecimal поможет вам. Следующий пример может быть полезным для вас

BigDecimal decimal=new BigDecimal(10.0);
    for (int i = 0; i < 10; i++) {
        decimal=decimal.add(new BigDecimal(.1));
        System.out.println(decimal.floatValue());

    }
1

что формат, который использует float, не может представлять все десятичные числа, поэтому точность иногда теряется.

использованиеBigDecimal вместо.

0

Java предоставляет класс из пакета импорта:import java.text.DecimalFormat называетсяDecimalFormat, Его подпись:

DecimalFormat myFormat = new DecimalFormat("0.0");

Он принимает аргумент String, где вы указываете, как вы хотите, чтобы форматирование отображалось.

Вот как вы можете применить его к своему коду:

DecimalFormat myFormat;
private static int getIndexOfUnits(float units) {
myFormat = new DecimalFormat("0.0");
int index = -1;
float addup = 0.10f;
for(float i = 1.00f; i < units; i=(float)i+addup) {
    index++;
    System.out.println("I = " + myFormat.format(i) + " Index = " + index);
}

return index;

}

В вашем println вы можете видеть, что класс DecimalFormat 'sformat() метод вызываетсяfloat i используя ссылку на объект myFormat на DecimalFormat - здесь происходит форматирование.

Похожие вопросы