Каков максимальный размер типа данных long long со знаком в 32-битном Linux

Я пытаюсь запустить приведенную ниже программу на 32-битной платформе Linux.

    int main()
{
unsigned long long  val  = 0;
val   = 140417 * 100000 + 92 + 1;
}

Выходное значение является некоторым значением мусора (1156798205).

После некоторых исследований я обнаружил, что:Вот

 long long size: 64 bits (MAX VALUE: signed long long = 144115188075855871, unsigned long long = 1073741823)

Приведенный выше код создает одну и ту же проблему с Visual Studio 2005 для обоих типов данных: unsigned long long и подписано long long.

Но согласно документации MSDN:
Вот

unsigned long long  8 byte  range of values  0 to 18,446,744,073,709,551,615

Мне интересно, как обрабатывать большой диапазон значений в 32-битной платформе Linux с помощью программы C ++.

Спасибо за помощь.

-1

Решение

Проблема в том, что, хотя вы используете 64-битный тип данных, в ваших вычислениях используются 32-битные значения, поэтому вы столкнулись с целочисленным переполнением. 140417 * 100000 14041700000 (0x344F356A0) в 64-битной версии, но 1156798112 (0x44F356A0) в 32-битной. Как вы можете видеть, 0x300000000 усекается из результата, так как он не вписывается в 32-битное значение.

Вы должны убедиться, что вы используете 64-битные вычисления, например:

typedef unsigned long long ulong64_t;

int main()
{
ulong64_t val = 0;
val = ulong64_t(140417) * ulong64_t(100000) + 92 + 1;
}

В качестве альтернативы используйте суффиксы целочисленной константы:

int main()
{
unsigned long long val = 0;
val = 140417i64 * 100000i64 + 92 + 1;
}

Или же:

int main()
{
unsigned long long val = 0;
val = 140417ull * 100000ull + 92 + 1;
}
0

Другие решения

Проблема в том, что тип целой константы без суффикса (например, 42) самый маленький из int, long int, long long int это может содержать его значение, и тип выражения определяется самим выражением, а не контекстом, в котором оно появляется.

Так что если int бывает 32 бит в вашей системе, то в этом:

unsigned long long val = 140417 * 100000 + 92 + 1;

константы 140417 а также 100000 (которые вмещаются в 32 бит) имеют тип intи умножение — это 32-битное умножение, которое переполняется, потому что произведение этих двух чисел не умещается в 32 бита. (Тип отдельного литерала корректируется в зависимости от его значения; тип большего выражения — нет.)

Самый простой способ избежать этого — использовать константы типа unsigned long long:

unsigned long long val = 140417ULL * 100000ULL + 92ULL + 1ULL;

(Бывает, что не все ULL суффиксы необходимы, но не мешает применять их ко всем константам в выражении.)

1

Если вы распечатываете: sizeof(unsigned long long)максимум 2 ^ (это значение) -1.

0

Мне интересно, как обрабатывать большой диапазон значений в 32-битной платформе Linux с помощью программы C ++.

добавлять #include <stdint.h> и использовать явный long long или предпочтительно int64_t или же uint64_t типы.

Недавний GCC (например, GCC 4.9, выпущенный в середине апреля 2014 года) может иметь __int128,

Если вы хотите обрабатывать очень большие числа (больше 263 в абсолютном значении), так называемый bignums вам понадобится библиотека Bignum (например, GMPlib), или язык, поддерживающий их изначально (например, Common Lisp, используя SBCL ….)

Кстати, следующая программа

#include <stdio.h>
int main () {
unsigned long long val = 0;
val = 140417 * 100000LL + 92 + 1;
printf ("val=%lld\n", val);
return 0;
}

работает на Linux x86 32 бит. Если вы опустите LL суффикс для 100000 (суффикс LL нужно было получить long long константа литерала 100000) вы получите предупреждение integer overflow in expressionв компилировать время с gcc -Wall hpfe.c -o hpfe ….

0
По вопросам рекламы [email protected]