У меня есть целочисленная переменная, которая может получить значение больше 4294967295.
Какой тип я должен использовать для него (длинный, или двойной, или что-то еще)?
У меня есть целочисленная переменная, которая может получить значение больше 4294967295.
Какой тип я должен использовать для него (длинный, или двойной, или что-то еще)?
В С++ нет переносимого способа сделать это, так как язык не указывает размер целочисленных типов (кроме sizeof char равен 1). Вам необходимо проконсультироваться со своей компиляционной документацией.
Используйте long long
и, если возможно, добавьте утверждение времени компиляции, чтобы этот тип был достаточно широким (smth как sizeof( long long ) >= 8
).
double
предназначен для с плавающей запятой, а не целого числа.
Try:
http://gmplib.org/ большое число.
http://mattmccutchen.net/bigint/ большой int.
Я не использовал ни одного, но я использовал похожие вещи в Java.
Я собираюсь предположить, что ваши номера будут соответствовать 64 бит. Если нет, то вам нужна арифметическая библиотека произвольной точности, например GMP.
В теории нет простого, переносимого способа выполнения 64-битных математических вычислений на С++. На практике большинство компиляторов С++ также поддерживают "старомодные" заголовки C, а C99 имеет хороший заголовок stdint.h.
Итак, прежде всего:
#include <stdint.h>
Затем используйте типы int64_t
(подписанные) и uint64_t
(без знака).
Оба предложения не хороши, потому что long long не является стандартным типом данных С++, а double - плавающей точкой.
Поскольку моя программа должна быть переносимой, я собираюсь #define свои собственные типы, которые подходят ко всем используемым компиляторам (visual studio и gcc):
#ifdef WIN32
#define unsigned_long_long unsigned __int64
#define long_long __int64
#else // gcc. Might not work on other compilers!
#define unsigned_long_long unsigned long long
#define long_long long long
#endif
Не используйте double, потому что:
cout.setf(ios::fixed);
cout << LONG_LONG_MAX << endl;
cout << double(LONG_LONG_MAX) << endl;
cout << LONG_LONG_MAX-100 << endl;
cout << double(LONG_LONG_MAX-100) << endl;
Вывод:
9223372036854775807
9223372036854775808.000000
9223372036854775707
9223372036854775808.000000
Я использую
uint64_t
Но это не стандартно.
если вам не нужны отрицательные числа, неподписанные длинные звуки, подобные большинству, которые вы можете получить.
Попробуйте TTMath. Все, что вам нужно сделать, это включить один заголовок, а затем объявить тип bignum, например:
typedef ttmath::UInt<100> BigInt;
который создает тип, который может содержать целые числа без знака от 0 до 2 ^ (32 * 100) -1.
Затем просто используйте BigInt
, где бы вы не использовали int
.
Конечно, вы можете выбрать любой размер, который вам нравится для параметра шаблона. 100 может быть излишним; -)
Только что реализовано, lib работает только на x86 и x64, но является кросс-платформой OS на этих процессорах.
Многие текущие компиляторы C/С++ имеют stdint.h или заголовок inttypes.h.
int_fast64_t
или int64_t
может быть вариантом (IMHO - самый портативный).
Насколько переносимой должна быть ваша программа? TR1 имеет cstdint и stdint.h, поэтому он, вероятно, поддерживается большинством современных компиляторов. Тогда есть Boost cstdint.hpp, который вы сможете использовать, если cstdint не поддерживается.
Двойные точки - это плавающие точки. Вероятно, вы должны долго использовать долго. Я не знаю, какой псевдоним является предпочтительным.
Если ваш компилятор не имеет долгого времени, вы можете реализовать их самостоятельно со структурой, содержащей два длинных, но вам нужно быть caurseful с переносом и т.д. Конечно, вы можете искать Арифметику с несколькими точками, такую как GMP
Просто из любопытства - я не думаю, что было бы слишком сложно закодировать свои собственные, если бы вы этого хотели. Я имею в виду, что все эти типы данных имеют предопределенные структуры, конечно, но вы могли бы, например, использовать структуру double
, которая использует экспоненты, и сделать что-то вроде этого:
чтобы удерживать ОЧЕНЬ большое число, за пределами шкалы двойника, создайте объект, который имеет две части: число и мощность до десяти,
поэтому, если вы хотите сохранить что-то вроде
1.1230123123 x 10 ^ (1000000000000000000000000000000000000000), который не поддерживается двойным, вы можете иметь 1.123... часть, хранящуюся в двойном, а затем мощность 10 в виде отдельного double/int/float (независимо костюмы), а затем взять его оттуда. Конечно, это может быть не самый лучший способ - и вам, вероятно, придется кодировать множество функций для деления, вычитания и т.д., Но это определенно было бы переносимым, так как вы использовали бы обычные типы данных. Возможность использования этого будет зависеть от того, что вы пытаетесь достичь, и планируете ли вы использовать это за пределами одного проекта, но я думаю, что это может быть возможным, если эти виды чисел являются абсолютным требованием