Операция <ведет себя как <= для определенных c значений двойной переменной - PullRequest
0 голосов
/ 24 апреля 2020

Я недавно начал изучать C ++ с самого начала и сейчас учусь у Бьярна Страуструпа "Принципы и практика программирования с использованием C ++". Существует упражнение, чтобы попытаться найти большее из двух чисел, введенных пользователем, и, если они меньше 0,01, выведите «Числа почти равны». Однако операция <, которую я использовал в своем операторе if, работает как <= по неизвестной причине. </p>

        if(num1<num2)
    {
        diff=num2-num1;
        std::cout<<"\nThe smaller value is: "<<num1;
        std::cout<<"\nThe larger value is: "<<num2;
        if(diff<0.01)
        {
            std::cout<<"\nThe numbers are almost equal";
        }
    }

Если я ввожу числа как 5 и 5.01, внутренний оператор if сработает. Но более странная вещь, которую я заметил, заключается в том, что оператор if не срабатывает, если введены 64 и 64.01. Это касается всех чисел от 64 до 127,99, после которых возвращается та же ошибка.

Я совершенно не понимаю, что является причиной этого.

1 Ответ

0 голосов
/ 25 апреля 2020

Следующая программа с hexfloat может показать вам детали.

К сожалению, извините, iomanip hexfloat будет выглядеть как cout << hexfloat << diff;, но при использовании флагов формата это комбинация ios::scientific | ios::fixed.

current                       diff                          
0x0.p+0                       0x1.47ae147ae147bp-7          <-- target
0x1.47ae147ae147bp-7          0x1.47ae147ae147bp-7          
0x1.47ae147ae147bp-6          0x1.47ae147ae147bp-7          
0x1.eb851eb851eb8p-6          0x1.47ae147ae147ap-7          similar

Посмотрите, как вывод шестнадцатеричного числа для target и следующих двух строк заканчивается на b. Затем следующий заканчивается на a, который достаточно отличается, чтобы быть меньше target, и выдает similar.

В любом случае сохраните это как cpp-double-compare.cpp и выполните:

make cpp-double-compare && echo 0.01 0.02 0.03 1.011 1.02 1.023 1.6 1.5 64.001 64.01 64 65 66 | ./cpp-double-compare

#include <cmath>
#include <iomanip>
#include <iostream>

using namespace std;

int main() {
  double current = 0.0, last = 0.0;
  constexpr int width = 30;
  constexpr double target = 0.01;
  constexpr ios::fmtflags fmt =
      ios::scientific | ios::fixed | ios::left | ios::showbase | ios::showpoint;

  cout << setw(width) << left << "current";
  cout << setw(width) << left << "diff";
  cout << endl;

  cout.setf(fmt);
  cout << setw(width) << 0.0;
  cout << setw(width) << target << setw(0) << "<-- target";
  cout << endl;

  while (cin >> current) {
    double diff = fabs(current - last);
    cout << setw(width) << current;
    cout << setw(width) << diff;
    if (diff < target) {
      cout << setw(0) << "similar";
    }
    cout << endl;
    last = current;
  }
  return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...