(*~\Глагол\Отделы\Обмен\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                            ОТДЕЛ Текст;
(*============================================================================* 
 * НАЗНАЧЕНИЕ: преобразование чисел в (из) текст(а)
 *----------------------------------------------------------------------------* 
 * В задачах <Из4хЦел> и <Из4хВещ> входное <описание> - это цепочка знаков,
 * содержащая и обычные знаки, которые просто переписываются в <текст>
 * и описатели представлений чисел, которые имеют следующее строение:
 *
 *   %[<номАрг>:,-,<ширина>,.<точность>]<вид>
 *
 *      Описатель представления начинается со знака '%'. Затем без
 *   пробелов следует ряд [необязательных] параметров:
 *
 *   [<номАрг>:]   - определяет номер аргумента, к которому относится
 *                   данный описатель
 *   [-]           - признак выравнивания влево
 *   [<ширина>]    - ширина поля вывода
 *   [.<точность>] - параметр точности
 *   <вид>         - знак, определяющий вид текущего аргумента
 *
 *      Знаки, определяющие вид аргумента:
 *
 *   'd'-Десятичное целое. Значение аргумента преобразуется в цепочку
 *       десятичных цифр. Если описатель представления содержит параметр
 *       точности, то текст должен содержать количество цифр, не
 *       менее указанного значения. Если значение содержит меньше
 *       цифр, то оно дополняется слева нулями.
 *
 *   'x'-Шестнадцатеричное целое. Значение аргумента преобразуется в цепочку
 *       шестнадцатеричных цифр. Если описатель представления содержит
 *       параметр точности, то текст должен содержать количество цифр, не
 *       менее указанного значения. Если значение содержит меньше
 *       цифр, то оно дополняется слева нулями.
 *
 *   'e'-Вещественное число в научном представлении.
 *       Значение преобразуется в цепочку вида "-ц,цц...E+ццц", где ц
 *       обозначает цифру. Отрицательные числа начинаются со знака минус.
 *       Перед десятичной запятой всегда имеется одна цифра. Общее
 *       число цифр (включая цифру до запятой) задается параметром точности.
 *       По умолчанию точность равна 15.
 *       После знака порядка "E" всегда присутствует знак плюс или
 *       минус и 3 цифры порядка.
 *
 *   'f'-Вещественное число с неподвижной запятой.
 *       Значение преобразуется в цепочку вида "-ццц,ццц...".
 *       Отрицательные числа начинаются со знака минус.
 *       Параметр точности показывает, сколько цифр будет после запятой.
 *       По умолчанию точность равна 2.
 *
 *   'g'-Вещественное число в общем виде.
 *       Значение преобразуется в кратчайшее десятичное представление
 *       (научное или неподвижное). По умолчанию число цифр, которое задается
 *       параметром точности, равно 15. Лишние нули удаляются, а запятая
 *       появляется только при необходимости. Результирующая цепочка
 *       представляется с неподвижной запятой, если число цифр левее запятой
 *       меньше или равно указанной точности и если значение больше
 *       или равно 0,00001. Иначе цепочка будет представлена в научном
 *       представлении.
 *
 *   'c'-Знак. Значение аргумента преобразуется в знак с порядковым
 *       номером, равным значению аргумента.
 *
 *      Если <вид> не принадлежит {'d','x','c','e','f','g'}, то параметры
 *   применяются не к аргументу, а к знаку <вид>.
 *      Числовые параметры могут извлекаться из текущего аргумента,
 *   если в качестве параметра выступает знак '*'.
 *      Знак 't' обозначает отсуп заданной ширины. По умолчанию ширина = 8.
 *============================================================================*)

ИСПОЛЬЗУЕТ
<*ЕСЛИ НЕ ЗАДАНО("МПГ") ТО*>
        (*  \Глагол\                   *)
  Асм     ИЗ "..\..\Отделы\Заграница\",   (* Асм - НЕ тригонометрия и спец.функции действительных шир.вещ.чисел на ASM *)

<*ИНАЧЕ*>          (* Малый ПГ*)
<*КОН*>
        (*  \Глагол\                   *)
 оБуквы   ИЗ "..\..\Отделы\Иное\",
 оЗнака   ИЗ "..\..\Отделы\Иное\";

ВИД
  РядЧисло- = ЦЕПЬ[32];

ВИД
  РядИз4хВещ = РЯД 4 ИЗ ШИРВЕЩ;
  РядИз4хЦел = РЯД 4 ИЗ ШИРЦЕЛ;

<*ЕСЛИ НЕ ЗАДАНО("МПГ") ТО*>

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ОсобенностьЧисла(
                            число:ШИРВЕЩ;
                           текст+:Текст.РядЧисло;
                              дл+:ЦЕЛ
                       ):КЛЮЧ; 
(*
 * Определяет и обозначает особые состояние <число>
 *----------------------------------------------------------------------------*
 * Ответ: ВКЛ, если <число> - не является числом
 *)
ПОСТ
  ПлюсБеск  = "+БЕСК";
  МинусБеск = "-БЕСК";
  НеЧисло   = "НЕЧ";
УКАЗ
  ВЫБРАТЬ
    Асм.Особенность(число)
  ИЗ
  | Асм.МинусБеск:           (* 1 *)
         текст:=МинусБеск;
      дл:=ДЛИНА(МинусБеск)
  | Асм.ПлюсБеск:            (* 2 *)
         текст:=ПлюсБеск;
      дл:=ДЛИНА(ПлюсБеск)
  | Асм.НеЧисло:             (* 3 *)
         текст:=НеЧисло;
      дл:=ДЛИНА(НеЧисло)
  ИНАЧЕ
    ВОЗВРАТ ОТКЛ 
  КОН;
    ВОЗВРАТ ВКЛ
КОН ОсобенностьЧисла;
 
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИзВещЕ-(
                            число:ШИРВЕЩ;
                         точность:ЦЕЛ;
                           текст+:Текст.РядЧисло;
                              дл+:ЦЕЛ
              );
(*
 * Вещественное число в научном представлении.
 *----------------------------------------------------------------------------*
 * До:    <число>    - преобразуемое число
 *        <точность> - цифр после запятой
 * После: <текст>    - текстовое представление числа
 *        <дл>       - его длина
 *)
ПЕР
  порядок:ЦЕЛ;              (* порядок числа *)
    цифры:Текст.РядЧисло;   (* цифры без точки *)
       пц:ЦЕЛ;              (* позиция цифры *)
УКАЗ
  ЕСЛИ
       ОсобенностьЧисла(число,текст,дл)
  ТО
    ВОЗВРАТ
  КОН;
  ЕСЛИ  точность <  0 ТО
        точность:=15
  АЕСЛИ точность > 18 ТО
        точность:=18
  КОН;
  дл:=0;
  ЕСЛИ
       число < 0
  ТО                     (* знак перед числом *)
    текст[дл]:='-';
    УВЕЛИЧИТЬ(дл)
  КОН;
  число:=МОДУЛЬ(число);
  порядок:=Асм.Порядок(число);
           Асм.ВЦифры (число,точность+1,цифры); (* 18 цифр *)
  ЕСЛИ
       цифры[0] = '0'
  ТО
    пц:=1
  ИНАЧЕ                  (* есть десятки *)
    пц:=0;
    УВЕЛИЧИТЬ(порядок)
  КОН;
  текст[дл]:=цифры[пц];  (* до запятой *)
  УВЕЛИЧИТЬ(дл);
  УВЕЛИЧИТЬ(пц);
  текст[дл]:=',';        (* запятая *)
  УВЕЛИЧИТЬ(дл);
  ПОКА
       точность > 0
  ВЫП                    (* после запятой *)
    текст[дл]:=цифры[пц];
    УВЕЛИЧИТЬ(дл);
    УВЕЛИЧИТЬ(пц);
    УМЕНЬШИТЬ(точность)
  КОН;
  текст[дл]:='E';        (* E *)
  УВЕЛИЧИТЬ(дл);
  ЕСЛИ
       порядок < 0
  ТО                     (* знак порядка *)
    текст[дл]:='-';
    порядок:=-порядок
  ИНАЧЕ
    текст[дл]:='+'
  КОН;
       пц:=дл+3;
  ПОКА
       пц > дл
  ВЫП                    (* порядок *)
    текст[пц]:=ВЗНАК(48+(порядок ОСТАТОК 10));
    порядок:=порядок ДЕЛИТЬ 10;
    УМЕНЬШИТЬ(пц)
  КОН;
  УВЕЛИЧИТЬ(дл,4);
  текст[дл]:=0X
КОН ИзВещЕ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИзВещФ-(
                            число:ШИРВЕЩ;
                         точность:ЦЕЛ;
                           текст+:Текст.РядЧисло;
                              дл+:ЦЕЛ
              );
(*
 * Вещественное число с неподвижной запятой.
 *----------------------------------------------------------------------------*
 * До:    <число>    - преобразуемое число
 *        <точность> - цифр после запятой
 * После: <текст>    - текстовое представление числа
 *        <дл>       - его длина
 *)
ПЕР
  порядок:ЦЕЛ;              (* порядок числа   *)
    цифры:Текст.РядЧисло;   (* цифры без точки *)
       пц:ЦЕЛ;              (* позиция цифры   *)
  вхчисло:ШИРВЕЩ;           (* двойник <число> *)
УКАЗ
  ЕСЛИ
       ОсобенностьЧисла(число,текст,дл)
  ТО
    ВОЗВРАТ
  КОН;
  вхчисло:=число;
  ЕСЛИ
       точность < 0
  ТО
       точность:=2
  КОН;
          дл:=0;
  ЕСЛИ
       число < 0
  ТО                                                     (* знак перед числом *)
    текст[дл]:='-';
    УВЕЛИЧИТЬ(дл)
  КОН;
       число:=МОДУЛЬ(число);
  ЕСЛИ
       число >= 10
  ТО
    порядок:=Асм.Порядок(число)+1
  ИНАЧЕ
    порядок:=1
  КОН;
  ЕСЛИ 
       точность+порядок >= РАЗМЕР(цифры)
  ТО                                                  (* совсем большое число *)
    Текст.ИзВещЕ(вхчисло,точность,текст,дл);
    ВОЗВРАТ
  КОН;
  Асм.ВЦифры(число,порядок+точность,цифры);
  ЕСЛИ
       цифры[0] = '0'
  ТО
    пц:=1
  ИНАЧЕ                  (* есть десятки *)
    пц:=0;
    УВЕЛИЧИТЬ(порядок)
  КОН;
  ПОКА
       порядок > 0
  ВЫП                    (* до запятой *)
    текст[дл]:=цифры[пц];
    УВЕЛИЧИТЬ(дл);
    УВЕЛИЧИТЬ(пц);
    УМЕНЬШИТЬ(порядок)
  КОН;
  текст[дл]:=',';        (* запятая *)
  УВЕЛИЧИТЬ(дл);
  ПОКА
       точность > 0
  ВЫП                    (* после запятой *)
    текст[дл]:=цифры[пц];
    УВЕЛИЧИТЬ(дл);
    УВЕЛИЧИТЬ(пц);
    УМЕНЬШИТЬ(точность)
  КОН;
  текст[дл]:=0X
КОН ИзВещФ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИзВещГ-(
                            число:ШИРВЕЩ;
                         точность:ЦЕЛ;
                           текст+:Текст.РядЧисло;
                              дл+:ЦЕЛ
              );
(*
 * Вещественное число в общем виде.
 *----------------------------------------------------------------------------*
 * До:    <число>    - преобразуемое число
 *        <точность> - цифр после запятой
 * После: <текст>    - текстовое представление числа
 *        <дл>       - его длина
 *)
ПЕР
     порядок:ЦЕЛ;              (* порядок числа   *)
       цифры:Текст.РядЧисло;   (* цифры без точки *)
          пц:ЦЕЛ;              (* позиция цифры   *)
     вхчисло:ШИРВЕЩ;           (* двойник <число> *)
  модвхчисло:ШИРВЕЩ;           (* двойник модуля <число> *)

УКАЗ
  ЕСЛИ
       ОсобенностьЧисла(число,текст,дл)
  ТО
    ВОЗВРАТ
  КОН;
  вхчисло:=число;
  ЕСЛИ 
       точность < 0
  ТО
       точность:=15
  АЕСЛИ
       точность > 18
  ТО
       точность:=18
  КОН;
  дл:=0;
  ЕСЛИ
       число < 0
  ТО                         (* знак перед числом *)
    текст[дл]:='-';
    УВЕЛИЧИТЬ(дл)
  КОН;
       число:=МОДУЛЬ(число); (* не ОСТАТОК, а ABS-величина <число> *)
  модвхчисло:=число;

  порядок:=Асм.Порядок(число);
  ЕСЛИ
       (порядок < -5)
      ИЛИ
       (порядок >= точность)
  ТО
    Текст.ИзВещЕ(вхчисло,точность,текст,дл);
    ВОЗВРАТ
  КОН;
  ЕСЛИ
       модвхчисло < 10
  ТО
    порядок:=0;
    число:=модвхчисло
  КОН;
      УВЕЛИЧИТЬ(порядок);
  ЕСЛИ
       точность+порядок >= РАЗМЕР(цифры)
  ТО                                       (* совсем большое число *)
    Текст.ИзВещЕ(вхчисло,точность,текст,дл);
    ВОЗВРАТ
  КОН;
  Асм.ВЦифры(число,порядок+точность,цифры);
  ЕСЛИ
       цифры[0] = '0'
  ТО
    пц:=1
  ИНАЧЕ                  (* есть десятки *)
    пц:=0;
    УВЕЛИЧИТЬ(порядок)
  КОН;
  ПОКА
       порядок > 0
  ВЫП                    (* до запятой *)
    текст[дл]:=цифры[пц];
    УВЕЛИЧИТЬ(дл); УВЕЛИЧИТЬ(пц);
    УМЕНЬШИТЬ(порядок)
  КОН;
  ПОКА
       (точность > 0)
      И
       (цифры[пц+точность-1] = '0')
  ВЫП                                 (* убираем нули *)
    УМЕНЬШИТЬ(точность)
  КОН;
  ЕСЛИ
       точность > 0
  ТО                     (* запятая *)
    текст[дл]:=',';
    УВЕЛИЧИТЬ(дл)
  КОН;
  ПОКА
       точность > 0
  ВЫП                    (* после запятой *)
    текст[дл]:=цифры[пц];
    УВЕЛИЧИТЬ(дл); УВЕЛИЧИТЬ(пц);
    УМЕНЬШИТЬ(точность)
  КОН;
  текст[дл]:=0X
КОН ИзВещГ;

<*ИНАЧЕ*>                (* Малый ПГ*)
<*КОН*>

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ЗадомНаПерёд(цепь+:ЦЕПЬ; дл:ЦЕЛ);
ПЕР
  поз:ЦЕЛ;
  зн:ЗНАК;
УКАЗ
       поз:=0;
   УМЕНЬШИТЬ(дл);
  ПОКА
       поз < дл
  ВЫП
    зн:=цепь[поз]; цепь[поз]:=цепь[дл]; цепь[дл]:=зн;
    УВЕЛИЧИТЬ(поз); УМЕНЬШИТЬ(дл)
  КОН   
КОН ЗадомНаПерёд;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ИзЦел(
                 число :ШИРЦЕЛ;
             основание,
             нужноцифр :ЦЕЛ;
                 текст+:Текст.РядЧисло;
                    дл+:ЦЕЛ
            );
(*
 * Преобразовать целое число в текстовое представление.
 *----------------------------------------------------------------------------*
 * До:    <число>     - преобразуемое число
 *        <основание> - основание системы счисления
 *        <нужноцифр> - нужное количество цифр результата
 * После: <текст>     - текстовое представление числа
 *        <дл>        - его длина
 *)
ПЕР
  можноцифр:ЦЕЛ;    (* количество цифр, которое возможно записать в результат *)
      цифра:ЦЕЛ;    (* текущая цифра *)
  меньшеНуля:КЛЮЧ;  (* ВКЛ, если число отрицательное *)
УКАЗ
  дл:=0;
                   можноцифр:=РАЗМЕР(текст)-1;
  ЕСЛИ
       нужноцифр > можноцифр
  ТО
    нужноцифр:=можноцифр
  КОН;
       меньшеНуля:=число < 0;
  ЕСЛИ
       меньшеНуля
  ТО
    ЕСЛИ
         основание = 16
    ТО
      меньшеНуля:=ОТКЛ;
      ЕСЛИ
           нужноцифр = -1
      ТО
           нужноцифр:=8
      КОН;
      можноцифр:=16
    АЕСЛИ
         число = МИН(ШИРЦЕЛ)
    ТО
      текст:="-9223372036854775808";
      дл:=ДЛИНА(текст);
      ВОЗВРАТ
    ИНАЧЕ
      УМЕНЬШИТЬ(нужноцифр); (* для знака в результате *)
      число:=-число
    КОН
  КОН;
  ПОВТОРЯТЬ
         цифра:=МОДУЛЬ(УЗК(число ОСТАТОК основание));
    ЕСЛИ
         цифра < 10
    ТО
      текст[дл]:=ВЗНАК(48+цифра)
    ИНАЧЕ
      текст[дл]:=ВЗНАК(55+цифра)
    КОН;
    число:=число ДЕЛИТЬ основание;
    УВЕЛИЧИТЬ(дл);
    ЕСЛИ
         дл >= можноцифр
    ТО
      число:=0
    КОН
  ДО ((число = 0) ИЛИ (число = -1)) И (дл >= нужноцифр);
  ЕСЛИ
       меньшеНуля
  ТО
    текст[дл]:="-";
    УВЕЛИЧИТЬ(дл)
  КОН;
  ЗадомНаПерёд(текст,дл);
  текст[дл]:=0X
КОН ИзЦел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИзЦел10-(
                число :ШИРЦЕЛ;
            нужноцифр :ЦЕЛ;
                текст+:Текст.РядЧисло
               );
(*
 * Преобразовать целое число в десятичное представление.
 *----------------------------------------------------------------------------*
 * До:    <число>     - преобразуемое число
 *        <нужноцифр> - нужное количество цифр результата
 * После: <текст>     - текстовое представление числа
 *)
ПЕР
  дл:ЦЕЛ;
УКАЗ
  ИзЦел(число,10,нужноцифр,текст,дл)
КОН ИзЦел10;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИзЦел16-(
                число :ШИРЦЕЛ;
            нужноцифр :ЦЕЛ;
                текст+:Текст.РядЧисло
               );
(*
 * Преобразовать целое число в шестнадцатеричное представление.
 *----------------------------------------------------------------------------*
 * До:    <число>     - преобразуемое число
 *        <нужноцифр> - нужное количество цифр результата
 * После: <текст>     - текстовое представление числа
 *)
ПЕР
  дл:ЦЕЛ;
УКАЗ
  ИзЦел(число,16,нужноцифр,текст,дл)
КОН ИзЦел16;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА Из4хЦелВещ(
                  описание-:ЦЕПЬ;
                     цАрги-:РядИз4хЦел;
                     вАрги-:РядИз4хВещ;
                     текст+:ЦЕПЬ
                 );
(*
 * Составить текст с 4-мя числами, используя описание текста.
 *----------------------------------------------------------------------------*
 * До:    <описание> - цепочка знаков, которая содержит обычные знаки,
 *                     которые просто переписываются в <текст> и описатели
 *                     представлений чисел (см. их описание выше)
 *        <цАрги>    - аргументы преобразования целого вида
 *        <вАрги>    - аргументы преобразования вещественного вида
 * После: <текст>    - выходной текст
 *)
ПЕР
    номАрг:ЦЕЛ;           (* номер текущего аргумента                           *)
       длт,
       дло:ЦЕЛ;           (* размер <текст> и <описание>                        *)
      позт,
      позо:ЦЕЛ;           (* позиции текущих знаков в <текст> и <описание>      *)
       зно:ЗНАК;          (* знак, прочитанный из <описание>                    *)
  ширина,
  точность:ЦЕЛ;           (* параметры вывода                                   *)
    налево:КЛЮЧ;          (* ВКЛ, если используется левое выравнивание          *)
     число:ЦЕЛ;           (* число из <описание>, используемое для параметра вывода *)
    текста:Текст.РядЧисло;(* текстовое представление текущего аргумента         *)
       дла:ЦЕЛ;           (* размер <текста>                                    *)

 (*.............................................подЗадача...*)
  ЗАДАЧА СледАрг();
  (* увеличить, если возможно, <номАрг> *)
  УКАЗ
    ЕСЛИ        номАрг < 4-1
    ТО
      УВЕЛИЧИТЬ(номАрг)
    КОН
  КОН СледАрг;
 (*.............................................подЗадача...*)
  ЗАДАЧА ЗнакО(описание-:ЦЕПЬ);
  (* читать следующий знак из <описание> *)
  УКАЗ
    ЕСЛИ позо >= дло ТО
      зно:=0X
    КОН;
    ЕСЛИ зно = 0X ТО
      ВОЗВРАТ
    КОН;
    зно:=описание[позо];
    УВЕЛИЧИТЬ(позо)
  КОН ЗнакО;
 (*.............................................подЗадача...*)
  ЗАДАЧА ЧислоО(описание-:ЦЕПЬ;
                   цАрги-:РядИз4хЦел);
  (* читать <число> для параметра из <описание> или из текущего аргумена *)
  УКАЗ
      число:=0;
    ЕСЛИ
         зно = '*'
    ТО
      число:=УЗК(цАрги[номАрг]);
      СледАрг();
      ЗнакО(описание)
    ИНАЧЕ
      ПОКА оЗнака.Цифра(зно) ВЫП
        число:=10*число+ВЦЕЛ(зно)-ВЦЕЛ('0');
        ЗнакО(описание)
      КОН
    КОН
  КОН ЧислоО;
 (*.............................................подЗадача...*)
  ЗАДАЧА ПараметрыО(описание-:ЦЕПЬ;
                       цАрги-:РядИз4хЦел);
  (* читать параметры <ширина>, <точность>, <налево> и <номАрг> из <описание> *)
  УКАЗ
    (* <ширина>, <налево> и <номАрг> *)
    КОЛЬЦО
      налево:=зно = '-';
      ЕСЛИ налево ТО ЗнакО(описание) КОН;
      ЧислоО(описание,цАрги);
      ЕСЛИ зно = ':' ТО
        номАрг:=число;
        ЗнакО(описание)
      ИНАЧЕ
        ВЫХОД
      КОН
    КОН;
    ширина:=число;
    (* <точность> *)
    число:=-1;
    ЕСЛИ зно = '.' ТО
      ЗнакО(описание);
      ЧислоО(описание,цАрги)
    КОН;
    точность:=число
  КОН ПараметрыО;
 (*.............................................подЗадача...*)
  ЗАДАЧА ЗнакТ(зн:ЗНАК;
           текст+:ЦЕПЬ);
  (* писать <зн> в <текст> *)
  УКАЗ
    ЕСЛИ позт < длт ТО
      текст[позт]:=зн;
      УВЕЛИЧИТЬ(позт)
    КОН
  КОН ЗнакТ;
 (*.............................................подЗадача...*)
  ЗАДАЧА ЗнакиТ(знаки-:ЦЕПЬ;
                    дл:ЦЕЛ;
                текст+:ЦЕПЬ);
  (* писать <дл> знаков <знаки> в <текст> *)
  ПЕР
    поз:ЦЕЛ;
  УКАЗ
    поз:=0;
    ПОКА поз < дл ВЫП
      ЗнакТ(знаки[поз],текст);
      УВЕЛИЧИТЬ(поз)
    КОН
  КОН ЗнакиТ;
 (*.............................................подЗадача...*)
  ЗАДАЧА ПробелыТ(кво:ЦЕЛ;
               текст+:ЦЕПЬ);
  (* писать <кво> пробелов в <текст> *)
  УКАЗ
    ПОКА кво > 0 ВЫП
      ЗнакТ(' ',текст);
      УМЕНЬШИТЬ(кво)
    КОН
  КОН ПробелыТ;

(*-zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz-*)
УКАЗ
  дло:=РАЗМЕР(описание);
  длт:=РАЗМЕР(текст);
  позо:=0;
  позт:=0;
  номАрг:=0;
  зно:=' ';
  ПОВТОРЯТЬ
    ЗнакО(описание);
    ПОКА зно = '%' ВЫП
      ЗнакО(описание);
      ЕСЛИ зно = '%' ТО
        ЗнакТ(зно,текст);
        ЗнакО(описание)
      ИНАЧЕ
        ПараметрыО(описание,цАрги);
        дла:=0;
        ВЫБРАТЬ оБуквы.ВСтрочную(зно) ИЗ
        | 't':
          ЕСЛИ ширина = 0 ТО
            ширина:=8
          КОН;
          ПробелыТ(ширина - (позт ОСТАТОК ширина),текст);
          ЗнакО(описание)
        | 'd':
          ИзЦел(цАрги[номАрг],10,точность,текста,дла);
          СледАрг();
          ЗнакО(описание)
        | 'x':
          ИзЦел(цАрги[номАрг],16,точность,текста,дла);
          СледАрг();
          ЗнакО(описание)
        | 'e':
          Текст.ИзВещЕ(вАрги[номАрг],точность,текста,дла);
          СледАрг();
          ЗнакО(описание)
        | 'f':
          Текст.ИзВещФ(вАрги[номАрг],точность,текста,дла);
          СледАрг();
          ЗнакО(описание)
        | 'g':
          Текст.ИзВещГ(вАрги[номАрг],точность,текста,дла);
          СледАрг();
          ЗнакО(описание)
        | 'c':
          ЕСЛИ (цАрги[номАрг] >= ВЦЕЛ(МИН(ЗНАК)) )
              И
               (цАрги[номАрг] <= ВЦЕЛ(МАКС(ЗНАК)) )
          ТО
            текста[0]:=ВЗНАК(цАрги[номАрг])
          ИНАЧЕ
            текста:="?"
          КОН;
          дла:=1;
          СледАрг();
          ЗнакО(описание)
        | 0X,'%':              (* ничего не делаем *)
        ИНАЧЕ
          текста[0]:=зно;
          дла:=1;
          УВЕЛИЧИТЬ(ширина);
          ЗнакО(описание)
        КОН;                   (* ВЫБРАТЬ ИЗ.. *)
        ЕСЛИ
             НЕ налево
        ТО
          ПробелыТ(ширина-дла,текст)
        КОН;
            ЗнакиТ(текста,дла,текст);
        ЕСЛИ
                налево
        ТО
          ПробелыТ(ширина-дла,текст)
        КОН
      КОН
    КОН;
    ЗнакТ(зно,текст)
  ДО зно = 0X
КОН Из4хЦелВещ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Из4хЦел-(
                 описание-:ЦЕПЬ;
              а0,а1,а2,а3 :ШИРЦЕЛ;
                    текст+:ЦЕПЬ
               );
(*
 * Составить текст с 4-мя целыми числами, используя описание текста.
 *----------------------------------------------------------------------------*
 * До:    <описание>   - см. Из4хЦелВещ()
 *        <а0>,..,<а4> - аргументы преобразования
 * После: <текст>    - выходной текст
 *)
ПЕР
  цАрги:РядИз4хЦел;      (* значения аргументов а0,...,а3 в целом виде        *)
  вАрги:РядИз4хВещ;      (* значения аргументов а0,...,а3 в вещественном виде *)
УКАЗ
  цАрги[0]:=а0;
  цАрги[1]:=а1;
  цАрги[2]:=а2;
  цАрги[3]:=а3;
  вАрги[0]:=а0;
  вАрги[1]:=а1;
  вАрги[2]:=а2;
  вАрги[3]:=а3;
  Из4хЦелВещ(описание,цАрги,вАрги,текст);
КОН Из4хЦел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИзЧЦел-(
                 описание-:ЦЕПЬ;
              а0,а1,а2,а3 :ШИРЦЕЛ;
                    текст+:ЦЕПЬ
              );
(*
 * Составить текст с 4-мя целыми числами, используя описание текста.
 *----------------------------------------------------------------------------*
 * До:    <описание> - см. Из4хЦелВещ()
 *        <а0>,,<а4> - аргументы преобразования
 * После: <текст>    - выходной текст
 *)
ПЕР
  цАрги:РядИз4хЦел;      (* значения аргументов а0,...,а3 в целом виде        *)
  вАрги:РядИз4хВещ;      (* значения аргументов а0,...,а3 в вещественном виде *)
УКАЗ
  цАрги[0]:=а0;
  цАрги[1]:=а1;
  цАрги[2]:=а2;
  цАрги[3]:=а3;
  вАрги[0]:=а0;
  вАрги[1]:=а1;
  вАрги[2]:=а2;
  вАрги[3]:=а3;
  Из4хЦелВещ(описание,цАрги,вАрги,текст);
КОН ИзЧЦел;

(*-----------------------------------------локальная ЗАДАЧА-------------------*)
ЗАДАЧА ВШирЦел0(в:ШИРВЕЩ):ШИРЦЕЛ;
УКАЗ
  ЕСЛИ
       (в >= МИН(ШИРЦЕЛ))
      И
       (в <= МАКС(ШИРЦЕЛ))
  ТО
    ВОЗВРАТ ВШИРЦЕЛ(в)
  КОН;
  ВОЗВРАТ 0
КОН ВШирЦел0;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       Из4хВещ-(
                 описание-:ЦЕПЬ;
              а0,а1,а2,а3 :ШИРВЕЩ;
                    текст+:ЦЕПЬ
               );
(*
 * Составить текст с 4-мя вещественными числами, используя описание текста.
 *----------------------------------------------------------------------------*
 * До:    <описание>   - см. Из4хЦелВещ()
 *        <а0>,..,<а4> - аргументы преобразования
 * После: <текст>    - выходной текст
 *)
ПЕР
  цАрги:РядИз4хЦел; (* значения аргументов а0,...,а3 в целом виде        *)
  вАрги:РядИз4хВещ; (* значения аргументов а0,...,а3 в вещественном виде *)
УКАЗ
  цАрги[0]:=Текст.ВШирЦел0(а0);
  цАрги[1]:=Текст.ВШирЦел0(а1);
  цАрги[2]:=Текст.ВШирЦел0(а2);
  цАрги[3]:=Текст.ВШирЦел0(а3);
  вАрги[0]:=а0;
  вАрги[1]:=а1;
  вАрги[2]:=а2;
  вАрги[3]:=а3;
  Из4хЦелВещ(описание,цАрги,вАрги,текст);
КОН Из4хВещ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ИзЧВещ-(
                 описание-:ЦЕПЬ;
              а0,а1,а2,а3 :ШИРВЕЩ;
                    текст+:ЦЕПЬ
              );
(*
 * Составить текст с 4-мя вещественными числами, используя описание текста.
 *----------------------------------------------------------------------------*
 * До:    <описание> - см. Из4хЦелВещ()
 *        <а0>,,<а4> - аргументы преобразования
 * После: <текст>    - выходной текст
 *)
ПЕР
  цАрги:РядИз4хЦел; (* значения аргументов а0,...,а3 в целом виде        *)
  вАрги:РядИз4хВещ; (* значения аргументов а0,...,а3 в вещественном виде *)
УКАЗ
  цАрги[0]:=Текст.ВШирЦел0(а0);
  цАрги[1]:=Текст.ВШирЦел0(а1);
  цАрги[2]:=Текст.ВШирЦел0(а2);
  цАрги[3]:=Текст.ВШирЦел0(а3);
  вАрги[0]:=а0;
  вАрги[1]:=а1;
  вАрги[2]:=а2;
  вАрги[3]:=а3;
  Из4хЦелВещ(описание,цАрги,вАрги,текст);
КОН ИзЧВещ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ВЦелое-(
                       цепь-:ЦЕПЬ;
                        поз+:ЦЕЛ;
                     цОтвет+:ШИРЦЕЛ;
                     вОтвет+:ШИРВЕЩ
              ):КЛЮЧ;
(*
 * Считывает из <цепь> начиная с позиции <поз> знаковое представление числа.
 *----------------------------------------------------------------------------*
 * Если это представление целого числа, то возвращает ВКЛ и записывает
 * значение числа в <цОтвет>, иначе возвращает ОТКЛ, а значение записывает
 * в <вОтвет>. 
 * По окончании <поз> указывает на следующий за числом знак.
 *)
ПЕР
  i,m,n,d,эксп:ЦЕЛ;
          мант:ШИРВЕЩ;
         цифры:ЦЕПЬ[64];
      знакМант,
      знакЭксп:ЦЕЛ;
          знак:ЗНАК;
        ошибка:КЛЮЧ;
         длина:ЦЕЛ;

 (*...........................подЗадача...*)
  ЗАДАЧА ЧитатьЗнакИзЦепи;               (* Читает следующий <знак> из <цепь> *)
  УКАЗ
    ЕСЛИ поз >= длина ТО
      знак:=0X
    ИНАЧЕ
      УВЕЛИЧИТЬ(поз);
      знак:=цепь[поз]
    КОН
  КОН ЧитатьЗнакИзЦепи;
 (*...........................подЗадача...*)
  ЗАДАЧА ДесятьВ(x:ЦЕЛ):ШИРВЕЩ;          (* 10 в степени <x> *)
  ПЕР
    ответ,множитель:ШИРВЕЩ;
  УКАЗ
    ответ:=1;
    множитель:=10;
    ПОКА x > 0 ВЫП
      ЕСЛИ НЕ ЧЕТ(x) ТО ответ:=ответ*множитель КОН;
      x:=x ДЕЛИТЬ 2;
      ЕСЛИ x > 0 ТО (* защита <множитель> от переполнения *)
        множитель:=множитель*множитель 
      КОН
    КОН;
    ВОЗВРАТ ответ
  КОН ДесятьВ;
 (*...........................подЗадача...*)
  ЗАДАЧА ЗнакВЦел(знак:ЗНАК;
             система16:КЛЮЧ):ЦЕЛ;
  УКАЗ 
    ЕСЛИ оЗнака.Цифра(знак) ТО
      ВОЗВРАТ ВЦЕЛ(знак)-ВЦЕЛ("0")
    АЕСЛИ система16 И ("A" <= знак) И (знак <= "F") ТО
      ВОЗВРАТ ВЦЕЛ(знак)-ВЦЕЛ("A")+10
    ИНАЧЕ
      ошибка:=ВКЛ
    КОН
  КОН ЗнакВЦел;

(*-zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz-*)
УКАЗ
  вОтвет:=0;
  цОтвет:=0;
  ошибка:=ОТКЛ;
  длина:=ДЛИНА(цепь);
  ЕСЛИ
       поз >= длина
  ТО                             (* ошибка: достигнут конец цепочки *)
    ВОЗВРАТ ВКЛ
  КОН;
                                 (* <поз> соответствует уже прочтённому знаку *)
  УМЕНЬШИТЬ(поз);
                                 (* пропускаем пробелы перед первой цифрой *)
  ПОВТОРЯТЬ
    ЕСЛИ поз >= длина ТО         (* ошибка: достигнут конец цепочки *)
      ВОЗВРАТ ВКЛ
    КОН;
    ЧитатьЗнакИзЦепи                              (* подЗадача *)
  ДО знак > " ";

  знакМант:=1;
  ЕСЛИ
       знак = "-"
  ТО
    знакМант:=-1;
    ЧитатьЗнакИзЦепи                              (* подЗадача *)
  АЕСЛИ
       знак = "+"
  ТО
    ЧитатьЗнакИзЦепи                              (* подЗадача *)
  АЕСЛИ
        НЕ оЗнака.Цифра(знак)
  ТО                            (* ошибка: не нашли числа *)
    ВОЗВРАТ ВКЛ
  КОН;
                                 (* читаем мантиссу *)
  i:=0; m:=0; n:=0; d:=0;
  КОЛЬЦО 
    ЕСЛИ
         оЗнака.Цифра(знак)
       ИЛИ
         (d = 0)
        И
         ("A" <= знак) И (знак <= "F")
    ТО
      ЕСЛИ
           (   m > 0) 
          ИЛИ 
           (знак # "0")
      ТО                         (* предстоящие нули пропускаем *)
        ЕСЛИ
             n < РАЗМЕР(цифры)
        ТО
          цифры[n]:=знак;
          УВЕЛИЧИТЬ(n)
        КОН;
        УВЕЛИЧИТЬ(m)
      КОН;
      ЧитатьЗнакИзЦепи;                           (* подЗадача *)
      УВЕЛИЧИТЬ(i)
    АЕСЛИ
         знак = ","
    ТО
      ЧитатьЗнакИзЦепи;                           (* подЗадача *)
      ЕСЛИ
           d = 0
      ТО         (* i > 0 *)
        d:=i
      ИНАЧЕ                      (* ошибка: неверный знак в записи числа *)
        ВОЗВРАТ ВКЛ
      КОН
    ИНАЧЕ
      ВЫХОД
    КОН
  КОН; (* 0 <= n <= m <= i, 0 <= d <= i *)

  ЕСЛИ d = 0 ТО (* целое *)
    ЕСЛИ
         n = m
    ТО
      i:=0;
      ЕСЛИ
           (знак = "H")
          ИЛИ 
           (знак = "X")
      ТО               (* 16-тиричное *)
        ЧитатьЗнакИзЦепи;                         (* подЗадача *)
        ЕСЛИ
             ( n > 16)
            ИЛИ
             ((n = 16) И (цифры[0] > "7"))
        ТО
                                 (* ошибка: слишком большое целое *)
          ВОЗВРАТ ВКЛ
        КОН;
        ПОКА i < n ВЫП
          цОтвет:=цОтвет*10H+ЗнакВЦел(цифры[i],ВКЛ);
          ЕСЛИ
               ошибка
          ТО                     (* ошибка: неверный знак в записи числа *)
            ВОЗВРАТ ВКЛ
          КОН;
          УВЕЛИЧИТЬ(i)
        КОН
      ИНАЧЕ            (* 10-тичное *)
        ПОКА i < n ВЫП
          d:=ЗнакВЦел(цифры[i],ОТКЛ);
          ЕСЛИ
               ошибка
          ТО                     (* ошибка: неверный знак в записи числа *)
            ВОЗВРАТ ВКЛ
          КОН;
          УВЕЛИЧИТЬ(i);
          ЕСЛИ
               цОтвет > (МАКС(ШИРЦЕЛ)-d) ДЕЛИТЬ 10
          ТО
                                 (* ошибка: слишком большое целое *)
            ВОЗВРАТ ВКЛ
          КОН;
          цОтвет:=цОтвет*10+d
        КОН
      КОН
    ИНАЧЕ                        (* ошибка: очень большое число *)
      ВОЗВРАТ ВКЛ
    КОН;
    цОтвет:=знакМант*цОтвет;
    ВОЗВРАТ ВКЛ
  ИНАЧЕ                (* дробная часть *)
    мант:=0;
    эксп:=0;
    ПОКА
         n > 0
    ВЫП                (* 0 <= мант < 1 *)
      УМЕНЬШИТЬ(n);

      мант:=(ЗнакВЦел(цифры[n],ОТКЛ)+мант)/10;
      ЕСЛИ
           ошибка
      ТО                         (* ошибка: неверный знак в записи числа *)
        ВОЗВРАТ ВКЛ
      КОН
    КОН;
    ЕСЛИ
         (знак = "E")
        ИЛИ
         (знак = "D")
    ТО
        ЧитатьЗнакИзЦепи;                         (* подЗадача *)
      знакЭксп:=1;
      ЕСЛИ
           знак = "-"
      ТО
        знакЭксп:=-1;
        ЧитатьЗнакИзЦепи                          (* подЗадача *)
      АЕСЛИ
           знак = "+"
      ТО
        ЧитатьЗнакИзЦепи                          (* подЗадача *)
      КОН;
      ЕСЛИ
           оЗнака.Цифра(знак)
      ТО
        ПОВТОРЯТЬ
          n:=ЗнакВЦел(знак,ОТКЛ);
          ЧитатьЗнакИзЦепи;                       (* подЗадача *)
          ЕСЛИ
               эксп <= (МАКС(ШИРЦЕЛ)-n) ДЕЛИТЬ 10
          ТО
               эксп:=эксп*10+n
          ИНАЧЕ                  (* ошибка: очень большое число *)
            ВОЗВРАТ ВКЛ
          КОН
        ДО НЕ оЗнака.Цифра(знак);
        эксп:=знакЭксп*эксп
      ИНАЧЕ                      (* ошибка: неверный знак в записи числа *)
        ВОЗВРАТ ВКЛ
      КОН
    КОН;
    УМЕНЬШИТЬ(эксп,i-d-m);       (* сдвиг десятичной точки *)
    ЕСЛИ
         эксп < 0
    ТО
      ЕСЛИ
           эксп <= -307
      ТО                         (* ошибка: очень маленькое число *)
        ВОЗВРАТ ВКЛ
      КОН;
      вОтвет:=мант/ДесятьВ(-эксп)
    ИНАЧЕ
      ЕСЛИ
           эксп  >  308
      ТО                         (* ошибка: очень большое число *)
        ВОЗВРАТ ВКЛ
      КОН;
      вОтвет:=мант*ДесятьВ(эксп)
    КОН
  КОН;
      вОтвет:=знакМант*вОтвет;
  ВОЗВРАТ ОТКЛ
КОН ВЦелое;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ВШирВещ-(
                       цепь-:ЦЕПЬ;
                        поз+:ЦЕЛ
               ):ШИРВЕЩ;
(*
 * Считывает из <цепь> начиная с позиции <поз> знаковое представление числа
 * и переводит его в ШИРВЕЩ вид. По окончании <поз> указывает на следующий
 * за числом знак
 *)
ПЕР
  ширцел:ШИРЦЕЛ;
  ширвещ:ШИРВЕЩ;
УКАЗ
  ЕСЛИ
       Текст.ВЦелое(цепь,поз,ширцел,ширвещ)
  ТО
    ВОЗВРАТ ширцел
  ИНАЧЕ
    ВОЗВРАТ ширвещ
  КОН
КОН ВШирВещ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ВВещ-(
                       цепь-:ЦЕПЬ;
                        поз+:ЦЕЛ
            ):ВЕЩ;
(*
 * Считывает из <цепь> начиная с позиции <поз> знаковое представление числа
 * и переводит его в ВЕЩ вид. По окончании <поз> указывает на следующий
 * за числом знак
 *)
УКАЗ
  ВОЗВРАТ УЗК(Текст.ВШирВещ(цепь,поз))
КОН ВВещ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ВШирЦел-(
                       цепь-:ЦЕПЬ;
                        поз+:ЦЕЛ
               ):ШИРЦЕЛ;
(*
 * Считывает из <цепь> начиная с позиции <поз> знаковое представление числа
 * и переводит его в ШИРЦЕЛ вид. По окончании <поз> указывает на следующий
 * за числом знак
 *)
ПЕР
  ширцел:ШИРЦЕЛ;
  ширвещ:ШИРВЕЩ;
УКАЗ
  ЕСЛИ
       Текст.ВЦелое(цепь,поз,ширцел,ширвещ)
  ТО
    ВОЗВРАТ ширцел
  ИНАЧЕ
    ВОЗВРАТ ВШИРЦЕЛ(ширвещ)
  КОН
КОН ВШирЦел;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~общедоступная ЗАДАЧА~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА
       ВЦел-(
                       цепь-:ЦЕПЬ;
                        поз+:ЦЕЛ
            ):ЦЕЛ;
(*
 * Считывает из <цепь> начиная с позиции <поз> знаковое представление числа
 * и переводит его в ЦЕЛ вид. По окончании <поз> указывает
 * на следующий за числом знак
 *)
УКАЗ
  ВОЗВРАТ УЗК(Текст.ВШирЦел(цепь,поз))
КОН ВЦел;

КОН Текст.
