@Jonhef

Как использовать целое число с размером больше чем 64 бита в C++?

Мне нужно что-то большее чем unsigned long long, но при этом целое(нужно деление по модулю), и не реализуя дополнительные сложные классы. Возможно ли такое?
  • Вопрос задан
  • 213 просмотров
Пригласить эксперта
Ответы на вопрос 3
vabka
@vabka
Токсичный шарпист
Если не реализовывать самостоятельно, то тогда брать стороннюю библиотеку (гугли: длинная арифметика/bigint)

А на сколько больше число? Сколько бит нужно?
Вообще вариант один:
Представить его как массив байт (тоесть условно вместо 8 байт - 16 или даже больше, или как энное число uint64)
И дальше руками реализовать арифметику.

Если хватит 128 бит и собираешь под x64, то можно взять нестандартный __int128_t
Ответ написан
Комментировать
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Придется самостоятельно реализовывать всякие операции. Это называется длинная арифметика.
Сложение, вычитание и даже умножение (если не надо очень быстро) - элементарно делаются.

Если надо делить нацело или брать по модулю маленького числа (<64 бит), то тоже элементарно - один цикл по цифрам числа.

Если же вам большое число надо делить на большое, то там чуть сложнее: надо будет деление в столбик реализовать. Это не высшая математика, но чуть-чуть подумать придется.
Ответ написан
@tifco
Сверхбольшие числа. Читал как-то главу о подобном в книге Р. Лафоре "ООП в C++". Передам идею по памяти. Т. к. читал давно уже. В общем-то ничего сложного.
Если нам не хватает значений одной переменной (беззнакового вещественного типа двойной точности (unsigned double)), ее максимального числа. А это, как известно, тип переменной (из простых типов), способной хранить достаточно большое максимальное число.
Как известно, при превышении значения переменной, она обнуляется и счет начинается с начала.
Если, для хранения сверхбольшого числа, нам не хватает одной такой переменной, то надо создать составную переменную. Или, иными словами, новый тип данных.
Вообще, переменная представляет собой простой счетчик.
Простой пример из жизни. Представим что я - малолетний ребенок и не умею считать более 1 десятка (умею только от 0 до 9). Но мне надо посчитать число большее, выходящее за эти пределы. Как быть?
А если, допустим, взять тот же механический счетчик (ленты в магнитофоне). То там идея в запоминании.
Дошел до максимума в счете (малые разряды (единицы)) -> перекинул на 1 единицу старшие разряды (десятки).
Логика действия: дошел до 9 (малое колесо), перевел его на 0 -> перевел в положение 1 (большее колесо).
Вот этот арифметический переход (десятки и единицы): 09 -> 10.
Другой пример. Как известно, человек, используя пальцы, способен посчитать только лишь до 10. Но это не предел.
Посчитать можно и до 25. То есть 5 в квадрате (2 степень).
Как? Запоминать число прохождений счета одной рукой, а другой - считать (проходить итерации раз за разом). Это тоже, по аналогии, с механическим счетчиком ленты.
Есть 2 руки: счетная и запоминающая.
Счетная пробегает от 1-5. Запоминающая - запоминает число проходов (пробегов) счетной руки.
счетная (цикл 1 - выражаясь компьютерным языком):
1 	  ->
1,2       ->
1,2,3     ->
1,2,3,4   -> 
1,2,3,4,5 ->

счетная (цикл 1) -> запоминающая (цикл 2):
1,2,3,4,5 -> 1
1,2,3,4,5 -> 1,2
1,2,3,4,5 -> 1,2,3
1,2,3,4,5 -> 1,2,3,4
1,2,3,4,5 -> 1,2,3,4,5

В итоге: 5 раз по 5 проходов - равно 25.
Логика или принцип что в механике, что в биологии одинаков. Реализации разные (техница или человек).

Это было предисловие. Используя тот же самый подход "склейки" нескольких переменных воедино, можно реализовать счет до сколь угодно большого числа.
Пусть, есть 3 переменные типа unsignet double. Именуемые: N1,N2 и N3. Максимальное значение каждой составляет N^m.
Момент "склейки" №1 двух переменных (N1 и N2): как только N1 дойдет до своего предела (программа должна отслеживать этот момент), ее следует обнулить (счет пойдет по второму (а в дальнейшем, по N-му) кругу) и увеличить на 1 переменную N2.
"Склейка" №2 (второй переменной N2 с третьей N3): как только N2 дойдет до своего предела (программа должна отслеживать и этот момент), ее следует обнулить и увеличить на 1 переменную N3.
Таким образом, совместно, они могут хранить в себе значение (цифру), содержащую огромное число знаков.
В текстовом редакторе (для общей наглядности), такая длинная строка из цифр и действия над ней - выглядят следующим образом. Пример. Это все одно число, логически (для наглядности), разделенное пробелом. Состоящее, соотвественно (слева направо), из переменных N1, N2 и N3.
spoiler
55555555555555555555555555555555555555555555555 55555555555555555555555555555555555555555555555 55555555555555555555555555555555555555555555555

Что происходит на "склейках"?
spoiler
00000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000 - начальное значение
...
99999999999999999999999999999999999999999999999 00000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000 - "склейка" № 1
00000000000000000000000000000000000000000000000 10000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000 - "склейка" № 1
...
99999999999999999999999999999999999999999999999 10000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000 - очередной переход
00000000000000000000000000000000000000000000000 20000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000 - очередной переход
...
99999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999 00000000000000000000000000000000000000000000000 - "склейка" № 2
00000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000 10000000000000000000000000000000000000000000000 - "склейка" № 2
...
99999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999 10000000000000000000000000000000000000000000000 - очередной переход
00000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000 20000000000000000000000000000000000000000000000 - очередной переход
...
99999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999 99999999999999999999999999999999999999999999999 - конечное значение

Отмечу момент, дабы не было путаницы. Ранее я упоминал что за основу взят тип переменной: беззнаковый, вещественный, двойной точности (unsigned double). Но далее, по тексту, пример счета я вел в беззнаковых, целых числах (типа usigned int). Он здесь как-то более понятен. Правда по максимальному значению, не помню, какой из них дает наибольшую величину. Вероятно, чем проще тип, тем больше он способен хранить. Не зря же мы берем именно беззнаковый тип. Это делается для того, чтобы отсечь отрицательную часть шкалы, увеличив, тем самым (за счет нее), ее положительную часть. Достигнув большего значения максимума. Тут уж сами определитесь с подходящими типами. Понятное дело, что 3-мя переменными - в качестве основы, мы не ограничены. :)
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы