Простой: он делает это так же, как вы , начиная с первого класса. За исключением того, что он не вычисляет в базе 10, он вычисляет в базе 4 миллиарда (и изменяется).
Подумайте об этом: с нашей системой счисления мы можем представлять только числа от 0
до 9
. Итак, как мы можем вычислить 6+7
без переполнения? Легко: мы делаем фактически переполнены! Мы не можем представить результат 6+7
как число от 0
до 9
, но мы можем переполниться на следующее место и представить его как два числа между 0
и 9
: 3 раза; 10 0 + 1 раз; 10 1 . Если вы хотите добавить два числа, вы добавляете их по цифрам справа и переполняете («перенос») слева. Если вы хотите умножить два числа, вам нужно умножить каждую цифру одного числа индивидуально на другое число, а затем сложить промежуточные результаты.
Арифметика BigNum (именно так обычно называют этот вид арифметики, когда числа больше, чем собственные машинные числа) работает в основном так же. За исключением того, что база не 10, и не 2, & ndash; это размер целого числа нативной машины. Таким образом, на 32-битной машине это будет основание 2 32 или 4 & times; 294 & thinsp; 967 & thinsp; 296.
В частности, в Ruby Integer
на самом деле является абстрактным классом, который никогда не бывает вдохновленным. Вместо этого у него есть два подкласса, Fixnum
и Bignum
, и числа автоматически перемещаются между ними, в зависимости от их размера. В MRI и YARV Fixnum может содержать 31 или 63-битное целое число со знаком (один бит используется для тегирования) в зависимости от собственного размера слова машины. В JRuby Fixnum может хранить целое 64-битное целое число со знаком, даже на 32-битной машине.
Самая простая операция - сложение двух чисел. И если вы посмотрите на реализацию +
, а точнее bigadd_core
в YARV's bignum.c , то это не слишком , чтобы следовать. Я тоже не могу читать C, но вы можете ясно увидеть, как он зацикливается на отдельных цифрах.