long int k=(long int)(2000*2000*2000);
приведенный выше расчет дает мне неправильный ответ на C. Что не так?Неверный ответ в C для расчета длинных чисел
long int k=(long int)(2000*2000*2000);
приведенный выше расчет дает мне неправильный ответ на C. Что не так?Неверный ответ в C для расчета длинных чисел
answer Holt является правильным, я просто оставляю это здесь caveat!
Вы могли бы попытаться использования:
long long int
вместо
long int
Однако в моей локальной машине, он не имеет никакого эффекта:
#include <stdio.h>
int main(void)
{
long int k=(long int)(2000*2000*2000);
printf("With long int, I am getting: %ld\n", k);
long long int n = 2000*2000*2000;
printf("With long long int, I am getting: %lld\n", n);
return 0;
}
Выход:
With long int, I am getting: -589934592
With long long int, I am getting: -589934592
Предупреждения:
../main.c:6:36: warning: integer overflow in expression [-Woverflow]
long int k=(long int)(2000*2000*2000);
^
../main.c:9:32: warning: integer overflow in expression [-Woverflow]
long long int n = 2000*2000*2000;
Даже это:
unsigned long long int n = 2000*2000*2000;
printf("With long long int, I am getting: %llu\n", n);
переполнится тоже.
Есть две проблемы в вашем коде:
long int
является (на большинстве архитектуры) не достаточно для хранения 8e9
.2000 * 2000 * 2000
операции выполняются с помощью «простых» int
, таким образом, int * int * int = int
так что вы бросили результат к int
, а затем в long int
.Вы должны использовать long long int
и указать, что вы хотите long long int
:
long long int k = 2000LL*2000LL*2000LL;
Обратите внимание на дополнительные LL
после 2000
говоря: "Это 2000, но как long long int
!".
2000
имеет тип int
, поэтому 2000*2000*2000
также имеет тип int
.
Предполагая, 32-битую int
(который на самом деле больше, чем стандарт требует, так как int
не требуется стандарт для представления значения больше, чем 32767
) максимального представимого значения составляет около 2,147,483,647
(запятые вставляется для удобства чтения) который составляет менее 8,000,000,000
.
Вы, вероятно, хотите сделать calcuation как 2000LL*2000*2000
, которое использует умножения быть слева направо ассоциативно, и будет способствовать все 2000
значения для long long int
перед выполнением умножения. Ваша переменная также должна быть типа long long int
, если вы хотите получить гарантию на возможность сохранения результата.
Если целочисленная константа C соответствует int
, она имеет тип int
. Таким образом, ваше выражение оценивается как:
long int k = (long int)((int)2000*(int)2000*(int)2000);
Если int
не достаточно большой, чтобы вместить результат умножения, вы получите подписанное переполнение целого числа и неопределенное поведение. Так что, если long
достаточно большой для хранения результата, вы должны написать:
long k = 2000L * 2000L * 2000L;
Суффикс L
заставляет тип литерала к long
(long
эквивалентно long int
).
Но на большинстве платформ, даже long
только тип 32-бит, так что вы должны использовать long long
, которые гарантированно иметь по крайней мере 64 бита:
long long k = 2000LL * 2000LL * 2000LL;
Суффикс LL
заставляет тип до long long
.
Вы не можете просто умножить значения вместе как обычные целые числа точности, а затем привести результат к более высокой точности, потому что результат уже переполнен в этой точке. Вместо этого операнды должны быть больше целых чисел точности, прежде чем они будут умножены. Попробуйте следующее:
#include <stdio.h>
int main(void)
{
long long int n = (long long int)2000*(long long int)2000*(long long int)2000;
printf("long long int operands: %lld\n", n);
return 0;
}
На моей машине, это дает:
long long int operands: 8000000000
долго ИНТ не достаточно, чтобы держать 2000 * 2000 * 2000. Используйте long long int. – Mukit09
ваши понятия .... –
Ну, насколько большой 2000 * 2000 * 2000? – qwr