2015-06-05 3 views
-1

что не так с моим кодом? его конвертируют дюймы и ноги и сравнивают их в метрах. если я вхожу 12 дюймов и 1 для ног, это говорит о том, что цифры не равны. Это известная проблема с g ++? Может ли кто-нибудь объяснить это мне?функция сравнения в g ++

#include <iostream> 
#include <cmath> 
using namespace std; 

int main() 
{ 
    double in, ft, m1, m2; 
    cin >> in >> ft; 
    m1 = in * 0.0254; 
    m2 = ft * 0.3048; 
    cout << m1 << '\t' << m2 << '\n' << endl; 
    // to show that both numbers are equal 
    if (m1 == m2) cout << "yay"; 
    else cout << "boo"; 
} 

Есть ли у кого-нибудь еще эта проблема?

+0

Возможный дубликат [Самый эффективный способ для поплавка и двойного сравнения] (http: // stackoverflow.com/questions/17333/most-effective-way-for-float-and-double-comparison) – NathanOliver

+0

Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой: http://docs.oracle.com/cd/E19957-01 /806-3568/ncg_goldberg.html –

+0

Сколько цифр вы напечатали? –

ответ

0

@Josh, добавьте в свой код и запустить его

cout << m2-m1; 

и будет удивляться, ответ не равен нулю

Для задачи в коде изменения типа данных с двойной плавать Фиксирует Задача

float in, ft, m1, m2; 
+0

Да, это сработало! Благодарю. –

0

То, что вы видите, является результатом неточного представления с плавающей запятой. Базовые 2^n числа с плавающей запятой не могут точно представлять все десятичные значения базового 10. Таким образом, когда вы делаете что-то простое, например, умножая 12 * 0.0254, вы получаете очень странный результат 0.3047999 ....... 6, тогда как если вы вычислите 1 * 0.3048, вы получите ожидаемый результат 0.3048. Проблема в том, что 0.0254 не хранится точно; вместо этого используется ближайшее приблизительное значение (примерно 0,0253999999 .... 98). Разница небольшая, но может стать заметной, когда вы используете неточное значение в вычислении, а затем сравниваете ее с другим значением, которое не страдает от проблемы округления, например 0,3048. Основное правило, о котором следует помнить, состоит в том, что вы должны never сравнить значения с плавающей запятой для равенства; вместо этого сравните их таким образом, чтобы допускать приемлемую ошибку, например. вместо сравнения значений следующим образом:

if(val1 == val2)... 

использовать что-то вроде

if(abs(val1 - val2) < 0.0000001)... 

так, что две переменные будут считаться равными, если их значения отличаются меньше, чем 1/10,000,000 (что довольно близко :-).

+0

Со всем уважением возьмите ручку и бумагу и Plz ... объясните, как у вас получилось 12 * 0.0254 = 0.3047999 ... ??? – Shivam

+0

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

+0

@Shivam - это не про ручку и бумагу. Если вы вычислите 12 * 0,0254 * точно *, используя перо и бумажный метод, вы получите правильный ответ. Однако арифметика с плавающей запятой, выполняемая компьютером, не является точной, отчасти из-за того, что может быть представлено только ограниченное подмножество действительных чисел, а также тот факт, что все вычисления также усекаются до ограниченной точности переменной. Что делает арифметику с плавающей запятой, выполненную компьютером очень неточным, даже если вы хорошо знаете, что делаете. – twalberg

0

Причина, по которой цифры не совпадают, состоит в том, что компьютеры используют двоичное представление чисел, что приводит к неточностям при попытке представления десятичных чисел.

Вы считаете, что это номер 0.3048 (потому что это то, что вы закодировали), но при компиляции компьютер может представлять это как ближайший эквивалент в двоичном формате (см. IEEE floating point для получения дополнительной информации). Таким образом, число может быть чем-то очень близким к 0.3048, но не совсем так.

После того, как вы выполнили свои расчеты, вы сравниваете числа, но если они не являются абсолютно идентичными в своих двоичных представлениях, они не будут совпадать.

Один простой способ его решения (но отнюдь не единственное решение) - это вычесть два операнда и проверить, насколько он близок к нулю. Если:

FABS (а - б) < 0,00001

(произвольное количество), то можно предположить, что значения совпадают.

+0

так ... не можете ли вы сравнить числа с плавающей запятой после манипуляций? –

+0

Я столкнулся с этой проблемой, когда я проходил через принципы программирования и практики, используя C++. Это было упражнение на стр. 124. –

+0

Было бы лучше, если бы вы могли предоставить решение для решения таких ситуаций ... tx – Shivam

Смежные вопросы