Я работал над встроенным проектом, когда я столкнулся с чем-то, что, по моему мнению, было странным поведением. Мне удалось воспроизвести его на кодовом коде (см. Ниже), чтобы подтвердить, но у меня нет других компиляторов C на моей машине, чтобы попробовать их на них.
Сценарий: у меня есть #define для наиболее отрицательного значения, которое может содержать 32-разрядное целое число, а затем я пытаюсь использовать его для сравнения со значением с плавающей запятой, как показано ниже:
#define INT32_MIN (-2147483648L)
void main()
{
    float myNumber = 0.0f;
    if(myNumber > INT32_MIN)
    {
        printf("Everything is OK");
    }
    else
    {
        printf("The universe is broken!!");
    }
}
Codepad link: http://codepad.org/cBneMZL5
Мне кажется, что этот код должен работать нормально, но, к моему удивлению, он выводит The universe is broken!!.
Этот код неявно передает INT32_MIN в float, но оказывается, что это приводит к значению с плавающей запятой 2147483648.0 (положительный!), хотя тип с плавающей точкой отлично способен представлять -2147483648.0.
Кто-нибудь может понять причину такого поведения?
  РЕШЕНИЕ КОДОВ. Как сказал Стив Джессоп в своем ответе, limits.h и stdint.h уже содержат правильный (рабочий) int диапазон define, поэтому я теперь использую их моего собственного #define
ПРОБЛЕМА/РЕШЕНИЕ ОБЪЯСНЕНИЯ РЕЗЮМЕ: Учитывая ответы и дискуссии, я думаю, что это хорошее резюме того, что происходит (обратите внимание: все еще читайте ответы/комментарии, потому что они дают более подробное объяснение)
-  Я использую компилятор C89 с 32-разрядным longs, поэтому любые значения, превышающиеLONG_MAXи меньшие или равныеULONG_MAX, за которыми следует постфиксL, имеют типunsigned long
-  (-2147483648L)на самом деле является унарным-на значенииunsigned long(см. предыдущую точку):-(2147483648L). Эта операция отрицания "обертывает" значение вокруг значенияunsigned long2147483648(поскольку 32-разрядныйunsigned longимеет диапазон0-4294967295).
-  Этот номер unsigned longвыглядит как ожидаемое отрицательное значениеint, когда он печатается какintили передается функции, потому что он сначала получает отличное отint, которое обертывает это вне -range2147483648вокруг-2147483648(поскольку 32-разрядныйintимеет диапазон от -2147483648 до 2147483647)
-  Приведение в float, однако, использует фактическое значениеunsigned long2147483648для преобразования, что приводит к значению с плавающей запятой2147483648.0.
