В C (99), LLONG_MAX
, максимальное значение long long int
должно быть не менее 9223372036854775807
. Максимальное значение unsigned long long int
должно быть не менее 18446744073709551615
, что составляет 2 − 1 (0xffffffffffffffff
).
Итак, инициализация должна быть:
unsigned long long int largestIntegerInC = 18446744073709551615ULL;
(Обратите внимание на ULL
.) Поскольку largestIntegerInC
имеет типа unsigned long long int
, вы должны напечатать его с правым спецификатором формата, который "%llu"
:
$ cat test.c
#include <stdio.h>
int main(void)
{
unsigned long long int largestIntegerInC = 18446744073709551615ULL;
/* good */
printf("%llu\n", largestIntegerInC);
/* bad */
printf("%d\n", largestIntegerInC);
return 0;
}
$ gcc -std=c99 -pedantic test.c
test.c: In function ‘main’:
test.c:9: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long long unsigned int’
Неверный второй printf()
, он может распечатать что угодно. Вы используете "%d"
, что означает, что printf()
ожидает int
, но получает unsigned long long int
, что является (скорее всего) не таким же размером, как int
. Причина, по которой вы получаете -1
, как ваш результат из-за (плохой) удачи, и тот факт, что на вашей машине цифры представлены с использованием представления двух дополнений.
Чтобы увидеть, как это может быть плохо, давайте выполним следующую программу:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int main(int argc, char *argv[])
{
const char *fmt;
unsigned long long int x = ULLONG_MAX;
unsigned long long int y = 42;
int i = -1;
if (argc != 2) {
fprintf(stderr, "Need format string\n");
return EXIT_FAILURE;
}
fmt = argv[1];
printf(fmt, x, y, i);
putchar('\n');
return 0;
}
На моем Macbook, запустив программу с "%d %d %d"
дает мне -1 -1 42
, и на машине Linux, и та же программа с тем же самым форматом дает мне -1 42 -1
. К сожалению.
В самом деле, если вы пытаетесь сохранить наибольшее количество unsigned long long int
в вашей largestIntegerInC
переменной, вы должны включить limits.h
и использовать ULLONG_MAX
. Или вы должны хранить Ассинг -1
в переменную:
#include <limits.h>
#include <stdio.h>
int main(void)
{
unsigned long long int largestIntegerInC = ULLONG_MAX;
unsigned long long int next = -1;
if (next == largestIntegerInC) puts("OK");
return 0;
}
В приведенной выше программе, как largestIntegerInC
и next
содержат наибольшее возможное значение для unsigned long long int
типа.
Все ответы ниже - это просто спекуляция. Это просто ** неопределенное поведение **, где разрешено что-либо. – Jens