c ++, если проблемы с оператором

0

Ниже приведена функция, которую я пытаюсь использовать, чтобы решить, переместил ли игрок шашки вверх или вправо. moveTo содержит десятичное число, подобное 5.2, а moveFrom будет содержать квадратное число 6.3, разница будет -1.1 и назначена moveValue (я проверяю ее с помощью оператора trace и правильно присваивает).

однако, когда он попадает в ifs, он не выходит как равный, и поэтому он запускает последний оператор if, однако, если я жестко кодирую -1.1 для moveValue он правильно оценивает. Любые идеи, почему это не правильно оценивается, будут большой помощью. Я опубликовал вывод о запуске программы под кодом:

int legalPlayerMove(float moveTo, float moveFrom)
{

    float moveValue=(moveTo-moveFrom);
    cout<<"trace move value"<<moveValue<<endl;


    if(moveValue==(-1.1))
        cout<<"moved up left"<<endl;
    if(moveValue==(-0.9))
        cout<<"moved up right"<<endl;
    if(moveValue!=-1.1||moveValue!=-.9)
        cout<<"that is not a legal move, please renter the square number you wish to move to."<<endl;

    return 0;
}
  • укажите местоположение части, которую хотите переместить
  • 6,3
  • теперь, пожалуйста, введите, где вы хотите переместить кусок
  • 5,2
  • отслеживать значение перемещения -1.1
  • это не законный ход, пожалуйста, введите номер квадрата, который вы хотите переместить.
  • Нажмите любую клавишу, чтобы продолжить. , ,
  • 2
    Не используйте == для сравнения значений с плавающей запятой. Когда вы вычитаете два значения с плавающей запятой, нет гарантии, что оно будет точно равно константе с плавающей запятой. Почему вы используете плавающую точку в любом случае? Что не так с использованием целых чисел?
  • 0
    возможный дубликат с плавающей точкой == когда-либо в порядке?
Показать ещё 1 комментарий
Теги:
if-statement

3 ответа

3
Лучший ответ

Всегда проблематично сравнивать переменные float или double с точными значениями float или double literal! Также использование operator== не является хорошей идеей в целом.

Используйте сравнение вместо минимальной разницы (aka epsilon) значений:

if(std::numeric_limits<float>::epsilon() + moveValue > 1.1) { // ...
}
  • 0
    Спасибо за ссылку, объясняющую эпсилон, ничего об этом не знал :)
1

Добавляя к сказанному, точное представление 0,1 или его кратность в двоичном выражении отсутствует. Это бесконечный ряд степеней 2.

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

Вы должны использовать целые пары для того, что вы делаете.

Вам неловко смешивать текстовое представление числа с его неотъемлемым значением.

  • 0
    спасибо за объяснение того, что происходит, я исправил это умножением на 10 и затем статическим приведением к int при сравнении.
0
#define EPS 0.000001
if(EPS + moveValue > 1.1){..}
...
  • 0
    Вы, вероятно, должны уточнить, почему вышесказанное является хорошей идеей.
  • 0
    Я думаю, что это очевидно для тех, кто знает о проблемах точности.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню