2016-10-29 11 views
1

Предположим, вы дали этот отрывок кода:Сравнение поплавки в C

Пример 1:

printf("Enter two real numbers: "); 
scanf("%f %f", &a, &b); 

if (a == b) //do something 

Мой вопрос: Нужно ли использовать некоторые «меры безопасности» при сравнении поплавки непосредственно взятый с клавиатуры?

Например, если я дал подобный код:

Пример 2:

printf("Enter two real numbers: "); 
scanf("%f %f", &a, &b); 
float x = a/b + 2 * a/3; 
float y = b/a + 3 * a/2; 
if (x == y) //do something 

Я знаю, что я должен использовать:

fabs(x - y) < RefValue 

для если своего состояния просто избегать потенциального возникновения false, даже если результат должен быть true. Но нужно ли это делать и в примере 1?

+0

'fabs (x-y) chux

+0

Спасибо за ваше замечание. Мне нужно это для небольших значений, так что это кусок кода, который мне нужен, и он достаточен для этой цели. – tyr

ответ

4

Это довольно безопасно предположить, что два числа вводимых с клавиатуры , используя тот же метод ввода в том же представлении символов в конечном итоге, как же двоичного числа. Это абсолютно не имеет отношения к точности - В конце концов, это воспроизводимость, одна из самых неотъемлемых черт компьютерных программ, на которые мы положимся. Эти два числа могут быть неточными и не точно представляют вход, но они должны быть одинаковыми. Короче говоря, ваш Пример 1 действителен.

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

0

Нет ничего о взятии с клавиатуры клавиатуры float, которая делает ее по своей сути менее точной, чем любая другая float. Сказав, что при взятии float с клавиатуры вы рискуете, что два числа, которые отличаются друг от друга, сохраняются как одно и то же значение, так как разница между двумя числами меньше, чем epsilon для одиночных прецизионных поплавков. Однако это ничем не отличается от любого другого использования поплавков. Таким образом, float, приобретенный у scanf, ничем не отличается от любых других float, и любые меры безопасности, которые вы использовали или не использовали бы обычно, должны использоваться с этими поплавками.

+0

Так что это не вычисления, которые «разрушают» точность, это способ хранения поплавка? – tyr

+2

Поплавки по своей сути неточны (см. [Здесь] (http://stackoverflow.com/questions/588004/is-floating-point-math-broken?rq = 1)), поэтому это будет проблемой, независимо от того, как получена поплавка. –

+2

(1/3 == 0.3333) - совсем другое дело, чем вводить один и тот же номер дважды с клавиатуры. Первая основана на предположении, что два разных способа выражения числа заканчиваются равенством, последний выполняет один и тот же фрагмент программы дважды на одном и том же входе - который ** должен ** давать те же результаты (даже если они одинаково неточно). – tofro