C ++ циклы с двойными - PullRequest
       37

C ++ циклы с двойными

1 голос
/ 12 августа 2011

Почему PRINT THIS в приведенном ниже коде никогда не печатается? Я уже cout << shiftx и shiftty, чтобы убедиться, что в какой-то момент они оба 0,3. </p>

for(double shifty=0; shifty < 2; shifty+=.1) {
    for(double shiftx=0; shiftx < 2; shiftx +=.1) {
        if((shiftx == 0.3) && (shifty == 0.3)) {
            cout << "PRINT THIS" << endl;
        }
    }    
}

Ответы [ 2 ]

9 голосов
/ 12 августа 2011

Золотое правило таково: избегайте проверок на равенство в числах с плавающей запятой.

Ни 0.1, ни 0.3 не могут быть точно представлены.

Стандартное чтение: Что должен знать каждый учёный-компьютерщик об арифметике с плавающей точкой .

Чтобы решить вашу конкретную проблему, вы должны выполнить итерацию и выполнить сравнение, используя целочисленные типы. Преобразовывать в типы с плавающей запятой можно только тогда, когда это действительно необходимо. e.g.:

for(int shifty=0; shifty < 20; shifty++) {
    for(int shiftx=0; shiftx < 20; shiftx++) {
        double shifty_double = shifty * 0.1;
        double shiftx_double = shiftx * 0.1;
        if((shiftx == 3) && (shifty == 3)) {
            cout << "PRINT THIS" << endl;
        }
    }    
}
4 голосов
/ 12 августа 2011

Вероятно, это связано с ошибками округления при использовании двойных чисел, поскольку 0,3 на самом деле не хранится как 0,3 точно внутри.

Один из способов сравнения пар - учесть некоторую ошибку в сравнении. Пример

if(abs(shiftx - shifty) < 0.000001) 
...