Примерно так, оптимизация( если нужна ) за Вами
| Код | program BigFactorial; const MAX_NUMBER_ORDER = 1024;{максимальный порядок числа} type TCipher = 0..9; TBigNumber = record MaxOrder : integer;{порядок числа} OrderNumbers : array [ 0..MAX_NUMBER_ORDER - 1 ] of TCipher;{массив для хранения цифр числа} end; function GetBigNumbersMult( var BigNumberRes, BigNumber1, BigNumber2 : TBigNumber ) : boolean; {функция возвращает завершилась ли операция умножения успехом, произведение 2 чисел BigNumber1 и BigNumber2 сохраняется в BigNumberRes} var i, j, iOrder, iMemoryValue : integer;{i, j - счетчики; iOrder - порядок; iMemoryValue - значение произведения 2 цифр}
begin {инициализация результата} BigNumberRes.MaxOrder := 0; for i := 0 to MAX_NUMBER_ORDER - 1 do BigNumberRes.OrderNumbers[ i ] := 0;
for i := 0 to BigNumber1.MaxOrder do{для всех цифр первого числа} for j := 0 to BigNumber2.MaxOrder do{для всех цифр второго числа} begin iOrder := i + j;{вычисление разряда} iMemoryValue := BigNumber1.OrderNumbers[ i ] * BigNumber2.OrderNumbers[ j ];{вычисление длинного значения}
while( ( iOrder < MAX_NUMBER_ORDER ) and ( iMemoryValue <> 0 ) ) do begin iMemoryValue := iMemoryValue + BigNumberRes.OrderNumbers[ iOrder ];{добавляем к длинному числу значение уже хранящееся на месте iOrder} BigNumberRes.OrderNumbers[ iOrder ] := iMemoryValue mod 10;{оставляем младший разряд} iMemoryValue := iMemoryValue div 10;{отбрасываем единицы} inc( iOrder );{увеличиваем порядок} end; if( iMemoryValue <> 0 ) then{вышли из цикла по первому условию и iOrder слишком велик} begin GetBigNumbersMult := false;{неудача} Exit;{выход} end; end;
{вычисляем порядок числа} i := MAX_NUMBER_ORDER - 1; while( ( i > 0 ) and ( BigNumberRes.OrderNumbers[ i ] = 0 ) ) do{ищем первый ненулевой показатель с конца массива} dec( i ); BigNumberRes.MaxOrder := i;{записываем порядок} GetBigNumbersMult := true;{умножение завершилось удачно} end;
procedure CreateBigNumberFromInteger( var BigNumber : TBigNumber; iNumber : integer ); {процедура заполняет запись BigNumber информацией о числе iNumber} var iOrder : integer;{iOrder - порядок} begin iOrder := 0;{инициализация порядка} BigNumber.OrderNumbers[ 0 ] := 0;{инициализация 0 порядка числа} while( iNumber <> 0 ) do begin BigNumber.OrderNumbers[ iOrder ] := iNumber mod 10;{вычисление цифры для нужного порядка} iNumber := iNumber div 10;{отрезаем единицы} inc( iOrder );{увеличиваем порядок} end; if( iOrder > 0 ) then{iOrder опережает порядок на 1, исключая единицы} dec( iOrder ); BigNumber.MaxOrder := iOrder;{записываем порядок} end;
function GetFactorial( var BigNumberRes : TBigNumber; iNumber : integer ) : boolean; {функция пытается вычислить факториал числа iNumber и если вычичление прошло удачно записывает результат в BigNumberRes и возвращает true, иначе возвращает false} var i, j : integer;{i, j - счетчики} BigNumber1, BigNumber2 : TBigNumber;{вспомогательные числа} begin if( iNumber < 0 ) then{факториал определен для целых неотрицательных чисел} begin GetFactorial := false;{факториал не получен} Exit;{выходим из функции} end;
if( iNumber > 2 ) then{ если число больше 2 } begin CreateBigNumberFromInteger( BigNumber1, iNumber );{запоминаем собственно число в BigNumber1} dec( iNumber );{уменьшаем исходное число} for i := iNumber downto 2 do{ далее необходимо iNumber - 1 умножение больших чисел для вычисления результата} begin CreateBigNumberFromInteger( BigNumber2, i );{создаем большое число из следующего множителя} if( not GetBigNumbersMult( BigNumberRes, BigNumber1, BigNumber2 ) ) then{если перемножение завершилось неудачей} begin GetFactorial := false;{факториал не получен} Exit;{выходим из функции} end else{иначе} begin {Перемещаем результат в BigNumber1} for j := 0 to BigNumberRes.MaxOrder do BigNumber1.OrderNumbers[ j ] := BigNumberRes.OrderNumbers[ j ]; BigNumber1.MaxOrder := BigNumberRes.MaxOrder; end; end; end else{иначе} begin if( iNumber = 0 ) then{факториал 0 = 1, иначе равен собственно числу} iNumber := 1; BigNumberRes.OrderNumbers[ 0 ] := iNumber; BigNumberres.MaxOrder := 0; end; GetFactorial := true;{раз дошли до конца функции, значит все посчитано} end;
procedure PrintBigNumber( var BigNumber : TBigNumber ); {процедура печати большого числа} var i:integer;{i - счетчик} begin for i := BigNumber.MaxOrder downto 0 do{для каждого разряда печатаем свою цифру} write( BigNumber.OrderNumbers[ i ] ); end;
var iNumber : integer;{вводимое число} BigNumberRes : TBigNumber;{результат вычисления факториала} bRes : boolean;{удалось ли вычислить факториал} begin writeln( 'Please enter a number (>=0):' ); repeat readln( iNumber );{ввод числа} if( iNumber < 0 ) then writeln( 'Invalid number. Number must be >=0. Please reenter number(>=0):' ); until iNumber >= 0; bRes := GetFactorial( BigNumberRes, iNumber );{узнаем хватило ли точности для вычисления} if( bRes ) then{точности хватило, печатаем результат} begin writeln( 'Results...' ); write( 'Factorial = ' ); PrintBigNumber( BigNumberRes );{печать большого числа} writeln; writeln( 'Order = ', BigNumberRes.MaxOrder + 1 );{добавляем единицу, так как у нас порядок начинается с 0} end else{точность мала, нужен больший по размеру массив} writeln( 'Error: BIG, REAL BIG NUMBER!!!' ); readln;{ждем ввода}
end.
|
|