Песни о Паскале - [101]

Шрифт
Интервал

Поскольку массив содержит символы ’0’…’9’, а не числа 0…9, при сложении символы преобразуем в числа и обратно (ведь символы складывать нельзя). Эти простые превращения выполняем по формулам.


>      цифра := Ord (символ_цифры) – Ord (’0’)

>      символ_цифры := Char (Ord (’0’) + цифра)


Вот эта чудесная программа целиком.


>{ P_46_2 – Сложение сверхбольших чисел }


>const CSize = 500; { размер массива }


>      { объявление типа для сверхбольшого числа }

>type

>      TBigNumber = array [1..CSize] of char;


>var BN1, BN2 : TBigNumber;       { два очень больших числа }


>{ Процедура распечатки сверхбольшого числа }

>procedure WriteBigNumber(var F: text; const aNum: TBigNumber);

>var i : integer;

>begin

>i:=CSize;

>while (i>0) and not (aNum[i] in ['1'..'9']) do Dec(i);

>if i=0 then Write(F, '0');

>while i>0 do begin

>      Write(F, aNum[i]);

>      Dec(i);

>end;

>Writeln(F); Writeln(F);

>end;


>{ Процедура сложения сверхбольших чисел "в столбик".

>Результат помещается в первое число, что равносильно оператору сложения

>aNum1 := aNum1 + aNum2 }


>procedure AddNumbers(var aNum1, aNum2 : TBigNumber);

>var i,j : integer;

>      n1, n2 : integer;       { слагаемые цифры }

>      sum, ovr : integer; { сумма и перенос }

>begin

>ovr:=0; { в начале переполнение = 0 }

>{ цикл по всем цифрам, кроме последней }

>for i:=1 to CSize-1 do begin

>      j:=i;       { j используется после завершения цикла }

>      { Если в текущей позиции пробел, то считаем его нулем,

>      а иначе символ цифры преобразуем в цифру 0..9 }

>      if aNum1[i]=' '

>      then n1:=0

>      else n1:=Ord(aNum1[i])-Ord('0'); { n1 = 0..9 }

>      if aNum2[i]=' '

>      then n2:=0

>      else n2:=Ord(aNum2[i])-Ord('0'); { n2 = 0..9 }

>      sum:= (n1+n2+ovr) mod 10;       { сумма sum = 0..9 }

>      ovr:= (n1+n2+ovr) div 10;       { перенос ovr = 0 или 1 }

>      { Преобразуем цифру в символ цифры }

>      aNum1[i]:= Char(sum + Ord('0'));

>end;

>{ Если было переполнение, то за последней цифрой помещаем единицу }

>if ovr<>0 then aNum1[j+1]:='1';

>end;


>var F : text; i : integer;


>begin       { === Главная программа === }

>Assign(F, ''); Rewrite(F);

>FillChar(BN1, SizeOf(BN1), ' '); FillChar(BN2, SizeOf(BN2), ' ');

>for i:=1 to CSize-1 do BN1[i]:= Char(Random(100) mod 10 + Ord('0'));

>for i:=1 to CSize-1 do BN2[i]:= Char(Random(100) mod 10 + Ord('0'));

>WriteBigNumber(F, BN1); { первое слагаемое }

>WriteBigNumber(F, BN2); { второе слагаемое }

>AddNumbers(BN1, BN2);

>WriteBigNumber(F, BN1); { сумма }

>Close(F); Readln;

>end.


Вы заметили, что количество сложений в цикле на единицу меньше размера массива? – одно место в массиве припасено на случай переноса из старшего разряда. Результат работы программы на моем компьютере таков.

Первое слагаемое (499 цифр):


>8803447475526346381115774817716923675204013515325625368435081217045581659031800071999794366

>1182651825637587203786736601358393989531415129060249427882941568716183991696120939861150054

>6931200667866376204115538852965830795649105020542397666292186509678053905826675950787561760

>5869708358318344949299824242208000929286578540423001609560508264356930728328745107168941254

>6971095113657279669411494318090578430589776576476782988688149478003857089789749459805075709

>20442289778748724626014927619547782761770630


Второе слагаемое (499 цифр):


>4301056320813339259127743021691072439999265735917637003180047595481028679918094988721008241

>5896167531551745866707619828471298816918833129959986427866428281363411295696463579032521755

>7777821776772170919033280201619190732499393489224796857416710264662385957326645736202490241

>1316796587449679809153393673306802289884085958345033422404931451426067305519212005730606726

>2742584874919295598665812780867323280259752302809107360806816867592608963920797222278187770

>61923128832709593717254099272079488419978116


Сумма (500 цифр):


>1310450379633968564024351783940799611520327925124326237161512881252661033894989506072080260

>7707881935718933307049435642982969280645024825902023585574936985007959528739258451889367181

>0470902244463854712314881905458502152814849850976719452370889677434043986315332168699005200

>1718650494576802475845321791551480321917066449876803503196543971578299803384795711289954798

>0971367998857657526807730709895790171084952887928589034949496634559646605371054668208326347

>982365418611458318343269026891627271181748746


Результат сложения нетрудно проверить в уме, – здесь калькулятор не только излишен, но и бесполезен.

Итоги

• Встроенные в язык типы данных – не единственный способ представления чисел. Для сверхбольших чисел годятся массивы чисел или символов. Действия с такими огромными числами – ввод, вывод, вычисления – требуют специальных процедур.

• Встроенная процедура FillChar заполняет нужным значением массив или переменную любого типа.

• Файловые переменные Input (для ввода с клавиатуры) и Output (для вывода на экран) встроены в язык. Они не требуют ни объявления, ни открытия, ни закрытия, и могут передаваться в качестве параметров процедур, как и другие файловые переменные.

А слабо?

А) Постройте сверхбольшие числа на основе строковых переменных (количество цифр – не более 255).

Б) Напишите процедуру для вычитания сверхбольших чисел. Или слабо? Учтите, что разность может быть и отрицательной!


Рекомендуем почитать
Выбор наследницы

Вторая часть трилогии "Мир Артефакта". Хранительница Артефакта, сама выбирает за кого ей выходить замуж, после, чего они привыкают к своим мужам, а некоторые из них влюбляются в них.


Горькое молоко. Золотой брегет. Тюремный шлейф

Книга «Горькое молоко» состоит из двух частей. Первая часть — «Золотой брегет» — повествует о сложной судьбе футболиста Ивана Беды, крёстном сыне известного вора в законе, который на свадьбу подарил Ивану золотой брегет. Вторая часть романа «Тюремный шлейф» рассказывает о племяннике Ивана Беды Сергее, которому тоже придётся повторить серьёзные жизненные моменты своего дяди, связанные с лишением свободы.


Учиться бывает опасно

Решив учиться в магической Академии, я пошла против воли отца. Ему не хотелось, чтобы я выходила за пределы нашей территории. В его глазах моя судьба — сидеть дома в четырех стенах, со временем выйдя замуж за того, на кого он укажет, за того, кому он сможет доверить нашу семейную тайну, размер и важность которой очень велики. Но меня такое решение не устроило и я, забрав с собой верного друга, сбежала, впервые в жизни поведя себя таким образом. Что ждет меня на этом пути? Что за таинственные личности появляются на моем пути? И что за судьба уготовлена мне пророчеством?


Разбитый Адам

Бог умер на кресте и сгнил, согласно научной картине мира, оставив своих детей. Либеральная Цивилизация решает покончить с "колыбелью человечества" и запускает в Солнце шаттлы с ядерными боеголовками. Теперь над Землей довлеет Багровый глаз. И он растет каждый час. Сможет ли Цивилизация сделать новый эволюционный шаг в виртуальный мир и вырезать из своих мозгов Архетип? Или Рай и жизнь для удовольствия – лишь дегенеративная сказка? Выдержит ли Прогресс экспансию Евразии или он обречен быть утопленным в животной религиозности? Знакомьтесь! Дьявол, заточенный в теле инвалида-гомосексуалиста, хлыстовка, ставшая Великой блудницей, самозванец, занявший опустевший трон Бога, а также отважные психонавты и другие неординарные личности сойдутся в напряженной схватке, чтобы решить, сохранит ли человек Образ Божий или станет чем-то другим? Роман-антиутопия "Разбитый Адам" повествует о развитии и столкновении апокалиптических проектов Евразии и западной цивилизации в середине 27-го столетия.


Круг Камней: Кровь эльфов

Давняя вражда между эльфами и людьми вспыхнула с новой силой. Эльфы завоевывают все новые территории и мечтают уничтожить Империю людей. Армия чудовищ, запечатанная в древнем эльфийском городе, оказалась на свободе. Неведомым образом все это связано с магией Круга Камней, о которой люди ничего не знают. Дознаватель Кристиан Уорден, несостоявшийся боевой маг, мечтавший о спокойной жизни советника лорда-правителя, оказался в эпицентре войны. Теперь ему придется совершить невозможное, чтобы выяснить правду о таинственном Круге и остановить врагов.


Новая религия

В книге рассказывается история главного героя, который сталкивается с различными проблемами и препятствиями на протяжении всего своего путешествия. По пути он встречает множество второстепенных персонажей, которые играют важные роли в истории. Благодаря опыту главного героя книга исследует такие темы, как любовь, потеря, надежда и стойкость. По мере того, как главный герой преодолевает свои трудности, он усваивает ценные уроки жизни и растет как личность.