Можливі дублікати:
Проблема з плаваючою комою в С
#include<stdio.h>
main()
{
int a,b;
float f;
scanf("%2d%3d%4f",&a,&b,&f);
printf("%d %d %f",a,b,f);
}
Коли я запускаю цю програму і вхід 2 4 56.8, він дає вихід 2 4 56.799999 ..... але я б очікував 2 4 56.8 .... чому це так?
Відповіді:
6 за відповідь № 1Це правильно. Числа з плаваючою точкою - це наближення. Так само, як 0.33333333 наближається до 1/3, 56.7999999 наближається до 56.8. Немає точного представлення з плаваючою точкою для 0.1.
Подивіться деякі з того, що написано:
- http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
- http://www.hack3r.com/forum-topic/what-every-programmer-should-know-about-floating-point-arithmetic
0 для відповіді № 2
56.8 не є точно представленим у форматі з плаваючою комою, що використовується вашим компілятором C. Подивитися Те, що повинен знати кожен комп'ютерний вчений про арифметику з плаваючою точкою (1991) Девід Голдберг.
0 для відповіді № 3
Всі числа з плаваючою точкою не можуть бути збережені якйого точне значення, оскільки безперервний простір числа домену з плаваючою комою відображається на дискретних рівнях. Наприклад, число з плаваючою точкою може бути збережено в IEEE754 єдиний точний формат. Він зберігає плаваючий номер у трьох частинах з 32 бітами пам'яті. Припустимо, що [a, b]
це два найближчі числа з плаваючою точкою, які можуть бути точно відображені за форматом IEEE754, але ми матимемо нескінченне число чисел з плаваючою точкою між a
і b
, в такому випадку ці цифри будуть апроксимуватися як з a
або b
. Це викликає неточність, яку ви відчуваєте.
Номер зберігається в нормованому форматі, хоча дуже незначне число може зберігатися в ненормалізованому форматі. Просто подивіться на документи.
Наприклад, у вашому випадку точність 56.8 IEEE754 одноточечного представлення буде такою:
- знак: 0 (1 біт)
- упереджений експонент: 10000100 (8 біт)
- мантиса: 11000110011001100110011 (23 біта)
Тепер, якщо ви перетворите цей номер на десяткову, то ви отримаєте
- знак 0 тобто значення позитивне
- 10000100 = 132 сума зміщення 127 тому показник = 132 - 127 = 5
- мантиса з прихованим бітом 1.11000110011001100110011
- після коректування десяткової крапки з показником (рухайте 5 місць праворуч): 111000.110011001100110011
- Ціла частина: 111000 = 2 ^ 5 + 2 ^ 4 + 2 ^ 3 = 56
- Дрібна частина: .110011001100110011 = 2 ^ -1 + 2 ^ -2 + 2 ^ -5 +2 ^ -6 + 2 ^ -9 +2 ^ -10 +2 ^ -13 +2 ^ -14 +2 ^ - 17 + 2 ^ -18 = 0,799999237
Тому, коли ви отримуєте значення з формату IEEE754 з точністю, він становить: 56.799999237, де ви зберегли 56.8
Ви можете грати з представленням IEEE754 тут: http://www.h-schmidt.net/FloatConverter/IEEE754.html
0 для відповіді № 4
Це може бути пов'язано з неточністю з плаваючою точкою.