Var St: string; z:string[10]; x:string[2]; i,j,k,m: integer; //новые переменные Begin Write('введите строку текста - St'); Readln(St); k:=0; //обнуляем на всякий случай z:='0123456789'; i:=1; for j:=1 to length(St) do //начало begin; for m:=1 to 10 do if St[j]=z[m] then inc(k); end; if k=0 then begin; writeln('в тексте нет цифр'); exit; end; //конец while i<=length(st)-1 do begin x:=copy(st,I,2); if (x[1]=x[2]) and (pos(x[1],z)<>0) then begin delete(st,i,2); insert('две',st,i); i:=i+1; end; i:=i+1; end; writeln('преобразованная строка ', st); End.
1. 16-битная арифметика со знаком предполагает, что самый левый бит используется для хранения знака. Отрицательные числа хранятся в дополнительном коде. При этом диапазон представления данных составляет -32768..32767. 32760+9 можно записать как 32767+2. Это позволит избежать перевода 32760 в двоичную систему счисления, а 32767 - это 15 двоичных единиц. В знаковом разряде, конечно же, ноль. После сложения в знаковом разряде появляется единица, что означает наличие отрицательного числа в дополнительном коде. Знаковый разряд мы не трогаем, а остальные инвертируем и арифметически прибавляем к полученному числу единицу. Тем самым переходим к прямому коду, который переводим в десятичную систему представления. И результат, конечно, же, будет со знаком минус, т.е. -32767. Вот к чему приводит переполнение разрядной сетки в целочисленной арифметике. Кстати, аппаратно оно не обнаруживается, поскольку криминала нет - просто +1 переходит в самый старший (левый) разряд. "Железо" ведь не знает, сколько разрядов мы отвели под представление чисел и как биты нужно рассматривать! Соответствующая картинка находится в первом вложении.
2. В восьмибитной арифметике все происходит аналогично. 127 представляется знаковым нулем и семью единицами в остальных разрядах, т.е. 01111111₂. Тройка - это 0..011₂ Складываем и получаем 10000010₂. Опять знаковый разряд единичный, инвертируем остальные: 11111101. А теперь прибавляем единицу и получаем 11111110₂. Числу 1111110₂ (знаковый разряд мы не учитываем) соответствует 126₁₀, а с учетом знака окончательно получаем -126.
3. Тут немного больше нужно повозиться. Арифметика снова 16-битная, диапазон представления чисел -32768..32767. Выпишем факториалы в пределах этого диапазона и одно значение вне его. 1!=1, 2!=2, 3!=6, 4!=24, 5"=120, 6!=720, 7!=5040, 8!=40320. Делаем вывод, что максимальное значение факториала можно вычислить для n=7 и n!=5040. Тогда n+1=8 и при его вычислении у нас возникнет арифметическое переполнение. Переведем число 5040 в двоичную систему и умножим его на 8, поскольку 8! = 7! × 8. Поскольку 8 = 2³, то умножение на 8 в двоичной системе равносильно сдвигу числа влево на три разряда. Подробности приведены на рисунке во втором вложении. Мы получим "странный" результат: 8! = -25216.
z:string[10];
x:string[2];
i,j,k,m: integer; //новые переменные
Begin
Write('введите строку текста - St');
Readln(St);
k:=0; //обнуляем на всякий случай
z:='0123456789';
i:=1;
for j:=1 to length(St) do //начало
begin;
for m:=1 to 10 do
if St[j]=z[m] then inc(k);
end;
if k=0 then
begin;
writeln('в тексте нет цифр');
exit;
end; //конец
while i<=length(st)-1 do
begin
x:=copy(st,I,2);
if (x[1]=x[2]) and (pos(x[1],z)<>0) then
begin
delete(st,i,2);
insert('две',st,i);
i:=i+1;
end;
i:=i+1;
end;
writeln('преобразованная строка ', st);
End.
32760+9 можно записать как 32767+2. Это позволит избежать перевода 32760 в двоичную систему счисления, а 32767 - это 15 двоичных единиц. В знаковом разряде, конечно же, ноль.
После сложения в знаковом разряде появляется единица, что означает наличие отрицательного числа в дополнительном коде. Знаковый разряд мы не трогаем, а остальные инвертируем и арифметически прибавляем к полученному числу единицу. Тем самым переходим к прямому коду, который переводим в десятичную систему представления. И результат, конечно, же, будет со знаком минус, т.е. -32767. Вот к чему приводит переполнение разрядной сетки в целочисленной арифметике. Кстати, аппаратно оно не обнаруживается, поскольку криминала нет - просто +1 переходит в самый старший (левый) разряд. "Железо" ведь не знает, сколько разрядов мы отвели под представление чисел и как биты нужно рассматривать! Соответствующая картинка находится в первом вложении.
2. В восьмибитной арифметике все происходит аналогично. 127 представляется знаковым нулем и семью единицами в остальных разрядах, т.е. 01111111₂. Тройка - это 0..011₂
Складываем и получаем 10000010₂. Опять знаковый разряд единичный, инвертируем остальные: 11111101. А теперь прибавляем единицу и получаем 11111110₂. Числу 1111110₂ (знаковый разряд мы не учитываем) соответствует 126₁₀, а с учетом знака окончательно получаем -126.
3. Тут немного больше нужно повозиться. Арифметика снова 16-битная, диапазон представления чисел -32768..32767.
Выпишем факториалы в пределах этого диапазона и одно значение вне его. 1!=1, 2!=2, 3!=6, 4!=24, 5"=120, 6!=720, 7!=5040, 8!=40320.
Делаем вывод, что максимальное значение факториала можно вычислить для n=7 и n!=5040. Тогда n+1=8 и при его вычислении у нас возникнет арифметическое переполнение. Переведем число 5040 в двоичную систему и умножим его на 8, поскольку 8! = 7! × 8. Поскольку 8 = 2³, то умножение на 8 в двоичной системе равносильно сдвигу числа влево на три разряда. Подробности приведены на рисунке во втором вложении. Мы получим "странный" результат: 8! = -25216.