Сравнивая поплавок и двойник - PullRequest
3 голосов
/ 26 января 2012
#include <stdio.h>
int main(void){
    float a = 1.1;
    double b = 1.1;
    if(a == b){
        printf("if block");
    }
    else{
        printf("else block");
    }
    return 0;
}

Печать: блок else

#include <stdio.h>
int main(void){
    float a = 1.5;
    double b = 1.5;
    if(a == b){
        printf("if block");
    }
    else{
        printf("else block");
    }
    return 0;
}

Печать: блок if

Какая логика стоит за этим?

Используемый компилятор: gcc-4.3.4

Ответы [ 3 ]

6 голосов
/ 26 января 2012

Это потому, что 1.1 не является точно представимым в двоичной переменной с плавающей точкой. Но 1.5 есть.

В результате представления float и double будут содержать несколько разные значения 1.1.

Вот в точности разница при записи в двоичном формате с плавающей точкой:

(float) 1.1 = (0.00011001100110011001101)₂
(double)1.1 = (0.0001100110011001100110011001100110011001100110011010)₂

Таким образом, когда вы сравниваете их (и повышается версия float), они не будут равны.

4 голосов
/ 26 января 2012
1 голос
/ 19 августа 2017

Точное значение 1.1 в двоичном виде - это неконечная дробь 1.00011001100110011001100 (1100) .... Двойная константа 1.1 - это 53-битное усечение / приблизительное значение этого мантисса .Теперь при конвертации во float мантисса будет представлена ​​в виде 24 битов.

Когда float конвертируется обратно в удвоение, мантисса теперь возвращается к 53 битам, но вся память цифр после 24 теряется - значение увеличивается до нуля, и теперь вы сравниваете(например, в зависимости от поведения при округлении)

1.0001100110011001100110011001100110011001100110011001

и

1.0001100110011001100110000000000000000000000000000000

Теперь, если вы использовали 1,5 вместо 1,1;

1.5 десятичное точно равно 1.1 в двоичном .Он может быть представлен точно в 2 битной мантиссе, поэтому даже 24 бита с плавающей точкой являются преувеличением ... то, что у вас есть

1.1000000000000000000000000000000000000000000000000000

и

1.10000000000000000000000

В последнем случае ноль, расширенный до двойного, будет

1.1000000000000000000000000000000000000000000000000000

, что, очевидно, является тем же числом.

...