#include <stdio.h>
int main() {
unsigned long long int num = 285212672; //FYI: fits in 29 bits
int normalInt = 5;
printf("My number is %d bytes wide and its value is %ul. A normal number is %d.\n", sizeof(num), num, normalInt);
return 0;
}
Вывод:
My number is 8 bytes wide and its value is 285212672l. A normal number is 0.
Я предполагаю, что этот неожиданный результат заключается в печати unsigned long long int
. Как вы printf()
a unsigned long long int
?
Используйте длинный модификатор ll (el-el) с преобразованием u (без знака). (Работает в Windows, GNU).
printf("%llu", 285212672);
Вы можете попробовать использовать библиотеку inttypes.h, которая дает вам типы, такие как
int32_t
, int64_t
, uint64_t
и т.д.
Затем вы можете использовать свои макросы, например:
uint64_t x;
uint32_t y;
printf("x: %"PRId64", y: %"PRId32"\n", x, y);
Это "гарантировано", чтобы не дать вам такой же проблемы, как long
, unsigned long long
и т.д., так как вам не нужно угадывать, сколько бит находится в каждом типе данных.
PRId64
, PRId32
определены?
inttypes.h
В течение долгого времени (или __int64) с использованием MSVS вы должны использовать% I64d:
__int64 a;
time_t b;
...
fprintf(outFile,"%I64d,%I64d\n",a,b); //I is capital i
Это потому, что% llu не работает должным образом под Windows и% d не может обрабатывать 64-битные целые числа. Я предлагаю использовать PRIu64 вместо этого, и вы найдете его переносимым для Linux.
Попробуйте это вместо:
#include <stdio.h>
#include <inttypes.h>
int main() {
unsigned long long int num = 285212672; //FYI: fits in 29 bits
int normalInt = 5;
/* NOTE: PRIu64 is a preprocessor macro and thus should go outside the quoted string. */
printf("My number is %d bytes wide and its value is %"PRIu64". A normal number is %d.\n", sizeof(num), num, normalInt);
return 0;
}
Выход
My number is 8 bytes wide and its value is 285212672. A normal number is 5.
%d
→ для int
%ld
→ для long int
%lld
→ для long long int
%llu
→ для unsigned long long int
Скомпилируйте его как x64 с VS2005:
% llu хорошо работает.
В Linux это %llu
, а в Windows это %I64u
Хотя я обнаружил, что он не работает в Windows 2000, там, кажется, есть ошибка!
Hex:
printf("64bit: %llp", 0xffffffffffffffff);
Вывод:
64bit: FFFFFFFFFFFFFFFF
Нестандартные вещи всегда странные:)
для длинной длинной части
в GNU L
, ll
или q
и под окнами я считаю, что ll
только
В дополнение к тому, что люди писали много лет назад:
main.c:30:3: warning: unknown conversion type character 'l' in format [-Wformat=]
printf("%llu\n", k);
Тогда ваша версия mingw не имеет значения по умолчанию c99. Добавьте этот флаг компилятора: -std=c99
.
Ну, один из способов заключается в том, чтобы скомпилировать его как x64 с VS2008
Это работает так, как вы ожидали:
int normalInt = 5;
unsigned long long int num=285212672;
printf(
"My number is %d bytes wide and its value is %ul.
A normal number is %d \n",
sizeof(num),
num,
normalInt);
Для 32-битного кода нам нужно использовать правильный спецификатор формата __int64% I64u. Так оно и будет.
int normalInt = 5;
unsigned __int64 num=285212672;
printf(
"My number is %d bytes wide and its value is %I64u.
A normal number is %d",
sizeof(num),
num, normalInt);
Этот код работает как для 32, так и для 64-битного VS-компилятора.