Сравнение удвоений

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

это код, который у меня есть до сих пор.

int main() { // VARIABLE DECLARATIONS double a; double b; while (a,b != '|') //WHILE A & B DO NOT EQUAL '|' { cin >>a >>b; cout << a << b << "\n" ; if (a<b) //IF A<B: SMALLER VALUE IS A cout << "The smaller value is:" << a << endl << "The larger value is:" << b << endl ; else if (b<a) //ELSE IF B<A cout << "The smaller value is:" << b << endl << "The larger value is:" << a << endl ; else if (b==a) cout << "The two numbers you entered are equal." << "\n" ; } } 

Следующий шаг заключается в том, что программа выписывает «числа почти равны», если два числа отличаются менее чем 1,0 / 10000000. Как мне это сделать?

Вот как я буду проверять равенство, без «фактора выдумки»:

 if ( // Test 1: Very cheap, but can result in false negatives a==b || // Test 2: More expensive, but comprehensive std::abs(ab)::epsilon()) std::cout << "The numbers are equal\n"; 

объяснение

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

Значение с плавающей запятой с двойной точностью может содержать наиболее значимые пятнадцать цифр числа (фактически ≈15.955 цифр). Поэтому мы хотим назвать два значения равными, если (приблизительно) их первые пятнадцать цифр совпадают. Чтобы выразить это другим способом, мы хотим назвать их равными, если они находятся в пределах одного масштабированного эпсилона друг друга. Это именно то, что вычисляет второй тест.

Вы можете добавить больше возможностей, чем один масштабированный epsilon, из-за более значительных ошибок с плавающей запятой, возникающих в результате итеративного вычисления. Для этого добавьте коэффициент ошибки в правую часть сравнения второго теста:

 double error_factor=2.0; if (a==b || std::abs(ab)::epsilon()* error_factor) std::cout << "The numbers are equal\n"; 

Я не могу дать вам фиксированное значение для error_factor , так как оно будет зависеть от количества ошибок, возникающих в ваших вычислениях. Однако при некотором тестировании вы должны найти разумную ценность, которая подходит для вашего приложения. Имейте в виду, что добавление (произвольного) коэффициента ошибки, основанного только на спекуляциях, вернет вас обратно на территорию фактора вымывания.

Резюме

Вы можете перенести следующий тест на (n встроенную) функцию:

 inline bool logically_equal(double a, double b, double error_factor=1.0) { return a==b || std::abs(ab)::epsilon()* error_factor; } 

std::abs(a - b) < 0.000001

Конечно, замените константу тем, что вы считаете «почти».

Просто проверьте, не отличаются ли они от этой суммы 🙂

 if ( std::abs(a - b) < 1.0 / 10000000 ) cout << "The numbers are almost equal.\n"; 
 if (a * 1.0000001 > b && a < b*1.0000001) 

Вы можете добавить значение ошибки (ваш 1.0 / 10000000.0), но, как правило, лучше использовать множитель, поэтому сравнение осуществляется на том же уровне точности.

Если вы хотите, чтобы тест масштабировался с помощью a и b, вы можете попробовать протестировать abs (a / b-1)

 abs(a - b) < 1.0 / 10000000 

Я предлагаю следующую статью: новая ссылка
(устаревшая ссылка-> Сравнение чисел с плавающей запятой )

Я также читаю книгу, так как мы не попали в std :: abs, я сделал что-то вроде этого:

 int main() { double i1,i2; while(cin>> i1 >> i2){ if (i1i2) { if ((i1-i2)<=0.0000001) cout << "Almost equal!"<