Рубрики

Сравнение числа с плавающей запятой в C

Предсказать вывод следующей программы на Си.

#include<stdio.h>

int main()

{

    float x = 0.1;

    if (x == 0.1)

        printf("IF");

    else if (x == 0.1f)

        printf("ELSE IF");

    else

        printf("ELSE");

}

Вывод вышеуказанной программы — « ELSE IF », что означает, что выражение «x == 0.1» возвращает false, а выражение «x == 0.1f» возвращает true.

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

#include<stdio.h>

int main()

{

   float x = 0.1;

   printf("%d %d %d", sizeof(x), sizeof(0.1), sizeof(0.1f));

   return 0;

}

The output of above program is "4 8 4" on a typical C compiler.
It actually prints size of float, size of double and size of float.

Значения, используемые в выражении, рассматриваются как двойные ( формат с плавающей запятой двойной точности ), если в конце не указано «f». Таким образом, выражение «x == 0.1» имеет двойное число с правой стороны и число с плавающей запятой, которое хранится в формате с плавающей запятой одинарной точности с левой стороны. В таких ситуациях float удваивается (см. Это ). Формат двойной точности использует больше битов для точности, чем формат одинарной точности.
Двоичный эквивалент 0,1 10 может быть записан как (0,00011001100110011…) 2, что будет идти до бесконечности (см. Эту статью, чтобы узнать больше о преобразовании). Поскольку точность с плавающей точкой меньше двойной, поэтому после определенной точки (23 с плавающей точкой и 52 с двойной) результат будет усечен. Следовательно, после преобразования float в double (во время сравнения) компилятор дополняет оставшиеся биты нулями. Следовательно, мы получаем другой результат, в котором десятичный эквивалент обоих будет различным. Например,

In float 
=> (0.1)10 = (0.00011001100110011001100)2
In double after promotion of float ...(1)
=> (0.1)10 = (0.00011001100110011001100000000000000000...)2
                                      ^ padding zeroes here
In double without promotion ... (2)
=> (0.1)10 = (0.0001100110011001100110011001100110011001100110011001)2

Hence we can see the result of both equations are different.
Therefore 'if' statement can never be executed.

Обратите внимание, что повышение значения типа float до удвоения может вызвать несоответствие, только когда значение (например, 0,1) использует больше битов точности, чем битов одинарной точности. Например, следующая программа на C печатает «IF».

#include<stdio.h>

int main()

{

    float x = 0.5;

    if (x == 0.5)

        printf("IF");

    else if (x == 0.5f)

        printf("ELSE IF");

    else

        printf("ELSE");

}

Выход:

IF

Здесь двоичный эквивалент 0,5 10 равен (0,100000…) 2
(Никакая точность не будет потеряна как в типе float, так и в типе double). Поэтому, если компилятор дополнит дополнительные нули во время продвижения, то мы получим один и тот же результат в десятичном эквиваленте для левой и правой части сравнения (x == 0,5).
Вы можете обратиться к представлению с плавающей точкой — Основы для представления чисел с плавающей точкой.

Эта статья предоставлена Абхай Рати и улучшена SHUBHAM BANSAL . Пожалуйста, напишите комментарии, если вы обнаружите что-то неправильное, или вы хотите поделиться дополнительной информацией по обсуждаемой теме

Рекомендуемые посты:

Сравнение числа с плавающей запятой в C

0.00 (0%) 0 votes