Целочисленная арифметика хороша тем, что вычисления в ней точны. Но взамен она требует для представления чисел достаточного большого количества байт и не случайно от переменных типа byte и integer, которые в памяти занимали 1 и 2 байта соответственно, создатели трансляторов с языка Паскаль пришли к четырехбайтному longint, а впоследствии и к восьмибайтному int64. Максимальное число, которое можно представить в longint, равно 2 147 483 647, а в int64 оно равно 9 223 372 036 854 775 807.
Много ли это в применении к нашей задаче?
Нам надо найти и вывести произведение четырехзначных чисел, значение которых не превышает 5000. Допустим, что все они равны 5000 и тогда количество членов в таком произведении может быть оценено при помощи несложного расчета.
Итак, мы можем получить произведение максимум ПЯТИ таких чисел.
А если использовать longint - вообще всего ДВА числа:
Но это по верхнему пределу. По нижнему, при значении, равном 1000, эти оценки увеличиваются до 6 и 3 чисел соответственно (достаточно количество разрядов в максимально представимом числе разделить на 3).
Что показывают эти расчеты? Всего лишь НЕПРИГОДНОСТЬ стандартной целочисленной арифметики языка Паскаль (а также других традиционных алгоритмических языков) для решения поставленной задачи в общем случае. Беда еще и в том, что большинство трансляторов строят программу так, что в ней переполнение разрядной сетки (т.е. выход числа за отведенный ему диапазон представления) по умолчанию НЕ КОНТРОЛИРУЕТСЯ. Другими словами, есть риск получить совершенно неверный результат и даже не подозревать об этом!
На помощь может прийти арифметика с плавающей точкой, пригодная для отображения действительно огромных чисел. Но у неё есть свой недостаток - она неточна. В языке Паскаль тип double может оперировать числами до приблизительно
, а вот количество точных цифр при этом составит 15-16. Но даже такая точность выше, чем дает стандартный тип longint.
На основании всего вышеизложенного и с учетом того, что тип int64 реализован далеко не во всех версиях языка Паскаль, можно принять следующий алгоритм:
1. Получаем искомые числа, генерируя не более, скажем, 50 элементов. Я считаю, что для любого разумного решения задачи такого количества чисел будет достаточно (мы просто не будем допускать, чтобы К превышало 50).
2. Нелепый критерий отбора чисел (квадрат первой цифры меньше квадрата
последней цифры числа) заменим разумным. Ведь цифра - суть однозначное число, а если квадрат одного числа меньше квадрата второго, то и сами числа находятся в таком же соотношении, поэтому зачем возводить в квадрат?. Итак, критерием отбора будет "первая цифра меньше последней цифры числа".
3. Находим произведение элементов массива в представлении double.
var
i,n,k:integer;
p:double;
begin
Randomize;
Write('Введите количество чисел К (1..50): '); Readln(k);
if (k<1) or (k>50) then Write('Неверное К')
else begin
p:=1;
Writeln('Отобранные случайные числа на интервале [1000;5000]');
for i:=1 to k do
begin
n:=Random(4501)+500; { диапазон [500;5000] }
if n>=1000 then
if (n div 1000)<(n mod 10) then
begin Write(n:5); p:=p*n end;
end;
Writeln;
if p>1 then Writeln('Произведение отобранных чисел равно ',p)
else Writeln('К сожалению, отобранных чисел нет')
end
end.
<em><u>Тестовые решения:</u></em>Введите количество чисел К (1..50): 15
Отобранные случайные числа на интервале [500;5000]
3208 4925 1279 2528 1637 4979 3536 4416 2116 3655
Произведение отобранных чисел равно 5.02832546192399E+34
Введите количество чисел К (1..50): 3
Отобранные случайные числа на интервале [500;5000]
3385 1177
Произведение отобранных чисел равно 3984145
Введите количество чисел К (1..50): 1
Отобранные случайные числа на интервале [500;5000]
3838
Произведение отобранных чисел равно 3838
Введите количество чисел К (1..50): 1
Отобранные случайные числа на интервале [500;5000]
К сожалению, отобранных чисел нет