Как печатать действительно большие числа на C++

У меня есть этот код

#include using namespace std; int main(int argc,char **argv) { unsigned long long num1 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999995LL; unsigned long long num2 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999996LL; unsigned long long num3 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999997LL; unsigned long long num4 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999998LL; unsigned long long num5 = 99999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999LL; cout << (unsigned long long)(num1 * num2 * num3 * num4 * num5) << endl; return 0; } 

Как видите, цифры огромны, но 9X_biginteger когда я подсчитываю, я получаю следующее: 18446744073709551496

Во 9X_c++ время компиляции я получаю следующие предупреждения:

warning: integer constant is too large for its type| In function `int main(int, char**)':| warning: this decimal constant is unsigned only in ISO C90| ... 

6
1

  • Я добавил к этому вопросу два тега, которые каж ...
5
Общее количество ответов: 5

Ответ #1

Ответ на вопрос: Как печатать действительно большие числа на C++

Ваш результат больше, чем длинный длинный 9X_cxx тип - вам нужно посмотреть на BigInteger или библиотеку 9X_cpp произвольной точности, что-то вроде gmp

22
0

Ответ #2

Ответ на вопрос: Как печатать действительно большие числа на C++

Эти числа не вписываются ни в какие типы 9X_c++ данных C++. Если вы хотите просто распечатать 9X_biginteger их, сохраните числа в строке. Если вы хотите 9X_cpp провести с ним математические вычисления, найдите 9X_cxx математическую библиотеку с произвольной 9X_biginteger точностью и используйте ее.

7
0

Ответ #3

Ответ на вопрос: Как печатать действительно большие числа на C++

Если вам нужны такие большие литералы в 9X_limits коде, вам придется ввести их как строковые 9X_cxx литералы и загрузить их в какой-то класс 9X_cpp BigInt. В настоящее время нет способа выразить 9X_cxx такие большие целочисленные литералы в исходном 9X_cpp коде (хотя мы надеемся, что C++ 0x устранит 9X_cxx этот недостаток).

Если вы используете библиотеку 9X_cpp BigInteger, обратите внимание на функцию stringToBigUnsigned в BigIntegerUtils.hh для построения 9X_c++ большого целого числа из строки.

#include "BigUnsigned.hh" #include "BigIntegerUtils.hh" BigUnsigned num1 = stringToBigUnsigned ( "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999999999999999999999999999999999999999999999999" "99999999999999999999999999999999999995" ); 

3
0

Ответ #4

Ответ на вопрос: Как печатать действительно большие числа на C++

Что вы пытаетесь сделать? Вы понимаете основы 9X_cxx двоичных и десятичных чисел? Почему 8 бит 9X_c++ содержат только значения от 0 до 255, 12 9X_cxx битов от 0 до 4095 и т. Д.? Сколько бит 9X_biginteger нужно для хранения интересующего вас числа? Или, лучше, какое 9X_biginteger количество номеров вы хотите создать? И 9X_limits вы используете девятки, чтобы увеличить 9X_biginteger число? А что насчет шестнадцатеричного 0xF 9X_limits ... вместо этого? Если вам нужно наибольшее 9X_cpp беззнаковое число (в пределах одного из 9X_biginteger стандартных целочисленных типов), почему 9X_c++ бы и нет:

unsigned long long a, b;

a = -1; // что 9X_c++ кажется неправильным смешиванием подписанного 9X_cpp и неподписанного, но это допустимо, число 9X_biginteger преобразуется в беззнаковое перед сохранением

b 9X_cxx = 0; б-; // делает то же самое, что и выше

Вам 9X_limits действительно нужна точность такого уровня? Вы 9X_c++ понимаете, что для умножения может потребоваться 9X_limits результат, вдвое превышающий размер каждого 9X_limits операнда? 0xFF * 0xFF = 0xFE01, если в этом 9X_cxx случае вы использовали 8-битные целые числа, вы 9X_cxx не смогли бы выполнить математику. Будет 9X_limits только хуже, если вы продолжите умножать 9X_biginteger 0xFF * 0xFF * 0xFF = 0xFD02FF.

Что пытаетесь 9X_biginteger сделать?


Ваш ответ:

Я раньше не видел Эйлера 9X_cxx номер 8. Звучит как хороший вопрос для собеседования, поскольку 9X_biginteger для его решения требуется всего несколько 9X_cpp строк кода.


Другой ваш ответ:

Цифры ...

Скорее 9X_biginteger всего, потому что у нас 10 пальцев (а может, и 9X_cxx 10 пальцев на ногах), мы вырастаем с «основанием 9X_limits 10». Наши часы по большей части основаны 9X_cpp на базе 60, но она была смешана с базой 9X_c++ 10, чтобы сделать ее более запутанной. В 9X_c++ любом случае, основание 10 означает, что 9X_c++ для каждого заполнителя числа у вас есть 9X_cxx одна из 10 уникальных цифр, когда вы достигаете 9X_biginteger максимума в этом месте, вы переходите к 9X_c++ следующему месту. Это все для начальной 9X_biginteger школы.

000
001
002
003
...
008
009 9X_cxx
010
011
012
...

Посмотрите, как самая 9X_cpp правая цифра состоит из 10 символов (0,1,2,3,4,5,6,7,8,9), и 9X_c++ когда она достигает последнего символа, она 9X_biginteger начинается заново, а цифра слева от он увеличивается 9X_cxx на единицу. Это правило верно для всех базовых 9X_c++ систем нумерации.

Это верно для основания 9X_limits 2, за исключением того, что здесь только 9X_c++ два символа, 0 и 1

000
001
010
011
100 9X_c++
101
...

То же верно и для восьмеричного, но 9X_c++ 8 символов (0,1,2,3,4,5,6,7)

000
001
002 9X_limits
003
004
005
006
007
010
011
012 9X_biginteger
013
...

То же самое верно для шестнадцатеричных, 16 9X_c++ символов (0,1,2,3,4,5,6,7,8,9, a, b, c, d, e, f)

000 9X_cxx
001
002
003
004
005
006
007
008 9X_cpp
009
00a
00b
00c
00d
00e
00f
010 9X_c++
011
012
013
...

Я собирался разобраться 9X_c++ в причинах использования двоичных файлов 9X_biginteger вместо других баз (например, 10) в компьютерах. Суть 9X_cxx в том, что легко иметь два состояния: включено 9X_cpp или выключено, или высокое и низкое. Два 9X_limits состояния похожи на два символа 1 и 0 в 9X_limits базе 2. Пытаться сохранить электронику настроенной 9X_cxx на более чем два состояния в пределах доступного 9X_cxx напряжения сложно, по крайней мере, раньше, поддерживать 9X_limits его около нуля вольт или выше некоторого 9X_cpp небольшого количества вольт - это сложно. относительно 9X_cxx просто, поэтому цифровая электроника использует 9X_cxx два состояния, двоичное.

Даже простая задача 9X_biginteger для человека в двоичной системе многословна, в 9X_limits простой математике для второго класса по-прежнему 9X_cpp много единиц и нулей. Итак, восьмеричный 9X_limits формат стал популярным, потому что он позволял 9X_limits вам мыслить группами по три биты, и вы могли 9X_biginteger использовать знакомые нам символы как числа 9X_c++ 0,1,2,3,4,5,6,7. Но группы по четыре, что 9X_cpp является другой степенью двойки, дает людям 9X_biginteger намного больше умственной вычислительной 9X_cpp мощности, чем восьмеричное, шестнадцатеричное 9X_limits основано на 4 битах, что также является 9X_cxx степенью 2. Нам пришлось добавить больше 9X_cxx символов к 10, которые мы позаимствовали 9X_cpp из традиционная арабская основа 10, поэтому 9X_cxx использовались первые 6 алфавита. Восьмеричное 9X_c++ число используется редко, если вообще когда-либо, вы 9X_c++ можете сказать кому-нибудь возраст, если 9X_biginteger они думают восьмеричное, а не шестнадцатеричное. (Я 9X_cpp из шестнадцатеричного поколения, но работал 9X_cpp с теми из восьмеричного поколения, которые 9X_limits борются с шестнадцатеричным, потому что 9X_cxx они не могут перейти от восьмеричного к 9X_limits двоичному к шестнадцатеричному в своем уме).

База 9X_c++ 10 в компьютере похожа на шестнадцатеричное 9X_cxx мышление обычного человека. компьютеры не 9X_cxx используют базу 10 (ну, для ленивых людей 9X_cxx они использовали bcd), они используют базу 9X_c++ 2. Десятичное число 1234 в компьютере на 9X_biginteger самом деле 0x4D2 или 0b010011010010. Это 9X_c++ как значение, скажем, вы хотите добавить 9X_c++ 1234 плюс какое-то другое число, которое 9X_limits вам нужно, это значение, которое не имеет 9X_biginteger ничего общего с символами 1, 2, 3 и 4. Но 9X_cxx для публикации этого ответа в stackoverflow 9X_cpp мы не используем число, которое мы используйте 9X_biginteger ASCII, поэтому 1234 в ascii - это 0x31, 0x32, 0x33, 0x34, что 9X_cxx важно знать для вашего решения Эйлера, предполагая, что 9X_biginteger 1000-значное число было предоставлено как 9X_c++ строка ascii, которая должна быть или вам 9X_limits придется преобразовать ее из двоичного в 9X_cpp ascii, поскольку проблема заключается в 9X_biginteger проблеме с основанием 10, а не с основанием 9X_c++ 2 по определению.

Итак, вернемся к тому, что 9X_cpp я спросил. Допустим, у вас есть 4 бита памяти 9X_cxx для хранения числа, какой размер числа вы 9X_cpp можете сохранить? Если вы думаете только 9X_c++ о базе 10, вы можете подумать, что это число 9X_biginteger - 9, потому что вы приучены думать об использовании 9X_biginteger самого большого символа в каждом месте хранения, 99999 9X_c++ - это наибольшее число, если у вас есть 9X_cxx 5 мест хранения в базе 10. Вернемся к четырем 9X_limits битам. хотя самый большой символ для одного 9X_limits бита - 1, поместите это число в каждое место 9X_limits хранения, которое вы получите 1111 (четыре 9X_c++ единицы). Просто взглянув на эти четыре 9X_c++ числа, вы сможете легко представить себе 9X_c++ восьмеричную и шестнадцатеричную версии 9X_limits того же восьмеричного числа 17 или шестнадцатеричной 9X_c++ F. Чтобы увидеть десятичную дробь, требуется 9X_cxx математика или, в данном случае, запоминание, это 9X_cxx десятичное число 15. Итак, самое большое 9X_cpp четырехбитное число, которое вы можете иметь, - это 9X_cxx 0xF или 15, а не 9. А как насчет 8-битного 9X_cxx числа? 0xFF или 255 (2 в восьмой степени 9X_biginteger минус один). Самый большой 16-битный номер? 65535 9X_cpp и др.

Когда я спрашиваю, сколько битов вы 9X_limits пытаетесь использовать, я имею в виду именно 9X_limits это. Посмотрите на это число 99999. Опять 9X_c++ же по основанию 10 вы можете подумать, что 9X_limits это самое большое число, но для компьютера 9X_c++ это только часть, десятичное число 99999 9X_limits - это 0x1869F, для хранения которого требуется 9X_cxx 17 бит памяти, самое большое 17-битное число, которое 9X_limits вы можете store - 0x1FFFF, то есть 131071, что 9X_cxx немного больше 99999. Поэтому, когда вы 9X_limits хотите думать на компьютере большими числами 9X_c++ и математикой, вы должны думать в двоичном 9X_cxx (или шестнадцатеричном) формате.

Изначально 9X_limits вы выполняли умножение, что до сих пор является 9X_cpp частью проблемы Эйлера, но то, о чем я спрашивал, было 9X_c++ связано с точностью и хранением битов. Вот 9X_cpp некоторые основы, и я не буду вдаваться 9X_cxx в них, но вы можете понять, почему мы полагаемся 9X_cpp на модули с плавающей запятой в компьютерах.

Возьмите 9X_limits наибольшее 4-битное число 1111 (двоичное), которое 9X_cxx составляет 15 десятичных знаков. Добавьте 9X_cxx к этому наибольшее четырехбитное число, и 9X_limits вы получите 15 + 15 = 30 = 0x1E или 11110 9X_biginteger в двоичном формате. Итак, чтобы сложить 9X_cxx два четырехбитных числа, вам понадобится 9X_limits пять битов для удержания ответа. Компьютеры 9X_limits сохраняют бит переноса для этого дополнительного 9X_c++ бита. По сути, целочисленные математические 9X_cxx функции сложения / вычитания в компьютере 9X_cxx позволяют иметь N + 1 бит. Так что, если 9X_biginteger это 32-битный компьютер, у вас в основном 9X_cxx есть 33 бита для сложения / подмножества.

Проблема 9X_cpp заключается в умножении и делении, которое 9X_cpp даже сегодня многие процессоры не поддерживают 9X_cxx (да, у многих нет процессора, и они только 9X_cxx добавляют и вычитают, иногда умножают, но 9X_cxx деление редко. Умножение и деление требует 9X_c++ большого количества электроники, компромисс 9X_limits вы можете делать их с помощью добавления 9X_biginteger и вычитания в программном обеспечении). Возьмите 9X_cxx умножение наихудшего случая для четырехбитной 9X_cxx системы 1111 * 1111 = 11100001, поэтому 9X_biginteger для хранения результата 4-битного умножения 9X_limits требуется 8 бит, вы быстро обнаружите, что 9X_c++ если бы у вас была 4-битная система, БОЛЬШИНСТВО 9X_biginteger умножений, которые вы хотите сделать, приведет 9X_limits к числу, которое не может быть сохранено 9X_cxx в 4 биты. Итак, когда я увидел, что вы берете 9X_biginteger 64-битные целые числа (unsigned long long 9X_cpp часто 64 бит) и умножаете четыре раза, это 9X_cxx означает, что вам нужно 64 * 5 или 320-битное 9X_limits целое число для хранения вашего ответа, вы 9X_c++ пытались поместить этот ответ в 64 большого 9X_cpp результата, который довольно часто, в зависимости 9X_c++ от компилятора и компьютера, будет с радостью 9X_biginteger делать и будет усекать верхние биты, оставляя 9X_limits вам нижние 64 бита результата, которые могут 9X_cpp легко выглядеть меньше, чем любой из ваших 9X_c++ операндов, что я думал вы могли бы сделать 9X_cxx сначала.

Плавающая точка - это не более чем 9X_cpp научная нотация, но в двоичной системе, если 9X_biginteger вы хотите умножить числа 1234 и 5678, используя 9X_biginteger научную нотацию, вы должны взять 1,234 * 10 9X_c++ ^ 3 на 5,678 * 10 ^ 3 и получить 7,007 * 10 9X_limits ^ 6. . Вы сохраняете точность и можете представлять 9X_biginteger более широкий диапазон чисел. Я не буду 9X_limits вдаваться в подробности, как это работает 9X_c++ в двоичном формате. Но это не сработает 9X_biginteger для вашего исходного вопроса.

Ах, последнее, что 9X_c++ нужно прояснить в своем вопросе / ответе. Отрицательные 9X_biginteger целые числа в двоичном формате. Из-за взаимосвязи 9X_cxx между сложением и вычитанием и базовой системой 9X_cpp вы можете сыграть некоторые уловки. Скажем, я 9X_limits хотел вычесть 1 из числа 7 (десятичного), используя 9X_cxx двоичный код. Нет такой вещи, как схема 9X_biginteger вычитания, вместо этого вы добавляете отрицательное 9X_cxx число, поэтому вместо 7-1 это действительно 9X_limits 7 + (-1), это имеет значение:

0111 + ???? = 0110

Какое 9X_cxx число можно добавить к 7, чтобы получить 9X_cpp 6 ... в двоичном формате?

0111 + 1111 = 0110

Отрицательные 9X_cpp числа в двоичном формате называются «дополнением 9X_cpp до двух», короче говоря, ответ - «перевернуть 9X_c++ и добавить 1». Как вы представляете минус 9X_c++ 1 в двоичном формате? возьмите плюс один 9X_biginteger 0001, затем переверните его, означая, что 9X_limits нужно сделать единицы нулями и нулями (также 9X_biginteger известными как дополнение до единиц) 1110, затем 9X_limits добавить единицу 1111. Минус один - это 9X_biginteger особое число в компьютерах (ну и везде), независимо 9X_cxx от того, сколько бит у вас есть представлен 9X_cpp как все. Итак, когда вы видите, что кто-то 9X_biginteger делает это:

символ без знака a;

a = -1;

Компилятор 9X_biginteger сначала смотрит на это -1 и думает ... 11111 9X_cpp (двоичный), затем он смотрит на знак равенства 9X_biginteger и другую сторону, о, вы хотите, чтобы все 9X_cpp были единицы, он видит, что у вас есть целое 9X_cpp число со знаком и беззнаковый, но преобразование 9X_biginteger состоит в том, чтобы просто переместить 9X_biginteger биты, поэтому вы говорите выше, что хотите 9X_biginteger a = 0xFF; (при условии 8-битного беззнакового 9X_cpp символа).

Некоторые компиляторы могут жаловаться, что 9X_limits вы пытаетесь сохранить отрицательное число 9X_cpp в беззнаковом числе. Другие компиляторы 9X_c++ будут смотреть на это -1 и рассматривать 9X_cxx его как 32-битную, или в наши дни, возможно, 64-битную 9X_limits целочисленную константу со знаком, а затем, когда 9X_biginteger она оценивает равные в 8-битной беззнаковой, вы 9X_c++ получите предупреждение о том, что вы не 9X_cpp можете сохранить -1 в подписанной или беззнаковый 9X_biginteger символ без приведения типа. Но если вы сделаете 9X_c++ это:

а = 0; а--;

Это понравится всем компиляторам. и 9X_cpp не буду жаловаться, он просто сжигает вычислительные 9X_cxx циклы во время выполнения, а не во время 9X_c++ компиляции.

Где-то друг рассказал мне о книге, в 9X_cxx которой последовательно выполняются двоичные 9X_cpp математические вычисления. Например, чтобы 9X_c++ отрицать число, обычно вы делаете инвертирование 9X_biginteger и объявление одного трюка, но с карандашом 9X_cxx и бумагой некоторые могут подсказать вам 9X_cpp другой трюк. Начиная справа, скопируйте 9X_cxx нули до первой единицы включительно, затем 9X_c++ инвертируйте после этого, так что минус 9X_cxx 2

0010
1110

Начиная справа, скопируйте 0, затем 9X_c++ первый, затем инвертируйте оставшиеся биты, когда 9X_biginteger идете влево.

минус 6

0110
1010

минус 4

0100 9X_c++
1100

Предположительно, существуют уловки 9X_cxx для сложения и вычитания (ну да, это несложно), но 9X_cpp также для умножения и деления. Если вы выполняете 9X_c++ их последовательно, вы можете выполнять 9X_limits бесконечно длинные математические вычисления 9X_c++ в двоичном формате с тем же alu. Если бы 9X_limits вы знали, как это сделать, вы могли бы реализовать 9X_limits это в программном обеспечении, и ваш исходный 9X_cpp вопрос об умножении больших констант (с 9X_cxx предположением о сохранении всей точности) тривиален 9X_c++ на любом компьютере.

3
0

Ответ #5

Ответ на вопрос: Как печатать действительно большие числа на C++

Ответ, который вы получили, 18446744073709551496, связан 9X_cxx с тем, что ваши 999 ... 9 усекаются при 9X_biginteger назначении long long, а также из-за переполнения 9X_cpp нескольких операций. Его детерминированный, но 9X_c++ на самом деле просто случайный набор битов.

1
0