BigInteger (PascalABC.NET)

Материал из Информационная безопасностя
Перейти к навигации Перейти к поиску

Pascal ABC.NET выбор школьника - Часть 3

BigInteger

Тип данных BigInteger – это библиотечный тип Microsoft .NET, позволяющий записывать и обрабатывать целые числа практически неограниченной длины.

Для данных типа BigInteger реализованы арифметические операции сложения, вычитания, умножения и деления. Операция деления, в отличие от других целочисленных типов данных, возвращает не вещественное значение, а результат целочисленного деления, имеющий тип BigInteger. Остаток целочисленного деления a на b можно получить с помощью традиционной для языка Паскаль операции a mod b.

С операцией возведения в степень дела обстоят немного сложнее. Функция Power не работает с типом BigInteger. Возвести значение типа BigInteger можно только в степень с показателем, приводящимся к типу integer, для чего используется операция **, либо вызов статической функции Pow из библиотеки .NET.

BigInteger.Pow(Основание, ПоказательСтепени);

Инициализация данных

Пока значение не превышает int64.MaxValue, т.е. в нем не больше 19 цифр – действительно, никаких проблем. А вот если цифр больше, то компилятор такое значение забракует, поскольку не сможет создать целочисленную константу необходимого размера. Выход – использовать строковое представление числа. Но тогда придется строку приводить к типу BigInteger.

var a := BigInteger.Parse('123456789012345678901234567890');

Метод .Parse предполагает, что строка содержит корректное изображение целого числа, возможно со знаком. В случае, если это не так, будет сгенерировано исключение и вы получите сообщение об ошибке, причем произойдет это не при компиляции, а во время выполнения программы: Ошибка времени выполнения: Не удалось выполнить синтаксический анализ значения».

Конечно, в реальной ситуации написать ерунду в литерале можно разве что себе назло. А вот получить некорректное значение при клавиатурном вводе вполне возможно. Для обработки подобной ситуации следует использовать другой метод:

1 var a: BigInteger;
2 if not BigInteger.TryParse(ReadlnString, a) then
3 begin
4  Print('Неверный ввод');
5  exit
6 end;

Преобразовать целочисленное значение или выражение к типу BigInteger можно посредством явного приведения типа, например BigInteger(26).

Приведение BigInteger к другому типу

Попытка явно привести значение типа BigInteger к другому целочисленному типу может привести к возникновению исключения на этапе выполнения программы. Действительно, количество цифр может оказаться чрезмерным и такое преобразование приведет к потере точности, что очень нежелательно в целочисленной арифметике. В то же время, преобразование к вещественному типу исключения не вызовет, поскольку сам факт использования данных такого типа свидетельствует о том, что программист заранее готов в какой-то степени жертвовать точностью.

1 ##
2 var a := BigInteger.MinusOne; // это -1
3 var b := integer(a);
4 a := BigInteger.Parse('1234567890123456789012345');
5 Print(b, real(a)) // -1 1.23456789012346E+24
6 var s := a.ToString; // к строке приводим обычным методом
7 Println(s) // 1234567890123456789012345

Пример решения задачи

Вычислить значение 123! (факториал). Подсчитать, сколько раз в нем встречается цифра «3»
1 ##
2 var p := BigInteger.One; // Число 1 типа BigInteger
3 for var i := 2 to 123 do
4  p *= i;
5 p.Println;
6 p.ToString.Count(t -> t = '3').Print;
12146304367025329675766243241881295855454217088483382315328918161829235892362167668831156960612640202170735835221294047782591091570411651472186029519906261646730733907419814952960000000000000000000000000000
16