Чому% f друкує великі значення, коли константи з плаваючою точкою передаються замість змінних?


9

Чому в даній програмі я отримав різні результати для кожного з них printf?

#include <stdio.h>
int main()
{
    float c = 4.4e10;
    printf("%f\n", c);
    printf("%f\n", 4.4e10);
    return 0;
}

І він показує такий вихід:

44000002048.000000
44000000000.000000

4
Поки що відповіді пояснюють, що 4.4e10це doubleконстанта, яка перетворюється floatв ініціалізацію, cале зберігається як a, doubleколи передається printf. Тим НЕ менше, ви могли б також хотіли б знати , що додавання fсуфікса робить його floatпостійна: друк 4.4e10fбуде показувати те ж значення , що результати ініціалізації cв 4.4e10f. Відмінність floatконстант від doubleконстант може бути важливим для якісної роботи з арифметикою з плаваючою комою.
Eric Postpischil

Чи називається цей спосіб перетворення чимось? Я хочу прочитати про це.
користувач10056563

Ви хочете знати, коли відбувається перетворення з doubleна floatв мові С? Або ви хочете знати, які значення є результатом конверсії, тобто які ефекти має конверсія? Або щось інше?
Eric Postpischil

Я не сумніваюсь ні у відповідях, ні в стандарті, але, коли я був молодим і навчався, Cми використовували printf("%f",x)для «а» floatі « printf("%lf",x)для» double. Коли все змінилося? І як би однозначно надрукуватиf (єдиний) float- printf("%hf",x)??
Адріан Моль

2
@Adrian %lfу printf - те саме, що і %f. floatУ змінному аргументі перетворюються в doubleкомпіляторі, так само , як shortотримує перетворено в int.
СС Енн

Відповіді:


9

A float- тип, який містить 32-бітове число з плаваючою комою, тоді як константа 4.4e10являє собою a double, яке містить 64-бітове число з плаваючою комою (тобто подвійне точне число з плаваючою комою)

При призначенні 4.4e10на cзначення 4.4e10не може бути представлено точно (помилка округлення в якості параметра називається мантиса), а найбільш можливе значення (44000002048) зберігається. Коли він передається printf, вона сприяє назад double, в тому числі помилки округлення.

У другому випадку значення - це doubleцілий час, без звуження і розширення, і трапляється так, що а doubleможе точно представляти значення.

Якщо ця поведінка небажана, ви можете оголосити її cяк doubleдещо більшу точність (але майте на увазі, що ви все-таки досягнете меж точності з часом).


3

Ви фактично друкуєте тут значення двох різних типів.

У першому випадку ви присвоюєте значення змінній типу float. Точність a floatстановить приблизно 6 або 7 десяткових цифр, тому, якщо значення не можна точно представити, ви побачите найближче значення, яке може бути представлене цим типом.

У другому випадку ви передаєте константу, 4.4e10яка має тип double. Цей тип має близько 16 десяткових цифр точності, і значення знаходиться в межах цього діапазону, тому друкується точне значення.


Чому він конкретно друкує 2048 року наприкінці?
користувач10056563

@ user10056563 Тому що це найближче число до 4.4e10, яке можна зберегти у 32-бітовому плаву.
dbush
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.