Неожиданное поведение от unsigned_int64;

#c #variables #unsigned-integer

#c #переменные #целое число без знака

Вопрос:

 unsigned__int64 difference;
difference=(64*33554432);
printf ("size %I64u n", difference);
difference=(63*33554432);
printf ("size %I64u n", difference);
  

первый # смехотворно велик. Второе число является правильным ответом. Как изменение его с 62 на 63 вызывает такое изменение?

Первое значение равно 18446744071562067968, второе значение равно 2113929216

Извините, значения были 64 и 63, а не 63 и 62.

Комментарии:

1. Не могли бы вы добавить результаты, которые вы видите? Не могли бы вы также опубликовать свой фактический код? (Этого не может быть, потому что нет difference3 ).

2. Упс, код очень простой.. Я, очевидно, имел в виду разницу, а не отличие3 извините

3. C не имеет unsigned__int64 . Вы используете расширение, зависящее от конкретной реализации, или библиотеку. Укажите свою платформу.

Ответ №1:

Если не указано иное, целочисленные литералы имеют тип int . Я бы предположил, что на платформе, на которой вы работаете, int является 32-разрядной. Таким образом, вычисление (64*33554432) переполняется и становится отрицательным. Затем вы преобразуете это в unsigned __int64 , так что теперь это значение возвращается к очень-очень большому положительному целому числу.

Вуаля:

 int main()
{
    int a1 = (64*33554432);
    int a2 = (63*33554432);

    printf("xn", a1);    // 80000000  (negative)
    printf("xn", a2);    // 7e000000  (positive)

    unsigned __int64 b1 = a1;
    unsigned __int64 b2 = a2;

    printf("6llxn", b1); // ffffffff80000000
    printf("6llxn", b2); // 000000007e000000
}
  

Комментарии:

1. @Matt: Это именно то, на что я намекаю.

Ответ №2:

В gcc это работает нормально и выдает правильное число в обоих случаях.

размер 2113929216 размер 2080374784

Может ли это быть ошибкой с printf? Используете ли вы MSVC или аналогичный? попробуйте выполнить это через отладчик и проверять разницу после каждой оценки. Если цифры выглядят прямо там, то это может быть просто проблема с printf. Однако в gcc на Linux это правильно.