(*~\Глагол\Отделы\ЧисАн\64\д\~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
(**)                         ОТДЕЛ дМатем;
(*============================================================================*
 * НАЗНАЧЕНИЕ: основные математические функции
 *    для действителльных чисел (с плавающей точкой) вида ШИРВЕЩ - 64 разряда
 *----------------------------------------------------------------------------*
 * ПРИМЕЧАНИЯ: после вызова задачи глобальная переменная <дМатем.код> может 
 *             стать # 0,
 *         это означает, что ответ задачи содержит не результат вычислений, а
 *             особое значение.
 *============================================================================*)

ИСПОЛЬЗУЕТ 
  ОС      ИЗ "..\..\..\..\Отделы\Обмен\",
АцМ32     ИЗ "..\..\..\..\Отделы\Заграница\ЧисАн\32\ц\", (*  АцМ32 - случайные 32-х разрядные целые числа на ASM
                                                          из Асм.отд - бывшие тригонометрия и спец.функции действительных шир.вещ.чисел на ASM iFPU387 *)
АдМ64     ИЗ "..\..\..\..\Отделы\Заграница\ЧисАн\64\д\"; (*  АдМ64 -          тригонометрия и спец.функции действительных шир.вещ.чисел на ASM iFPU387 *)

(*----------------------------------------------------------------------------*
 * Вид, задающий точность вычислений
 *----------------------------------------------------------------------------*)
ВИД
        (* вид Вещ - это двойная точность - 64 разряда (18 десятичных знаков) *)
  Вещ- = ШИРВЕЩ;                      (* глобально *)

(*----------------------------------------------------------------------------*
 * Код ошибки после выполнения функций
 *----------------------------------------------------------------------------*)
ПОСТ
  ВНЕОБЛАСТИ-   = -1;    (* аргумент вне области определения функции *)
  ОСОБЕННОСТЬ-  = -2;    (* особенная точка                          *)
  ПЕРЕПОЛНЕНИЕ- = -3;    (* переполнение результата                  *)
  ОБНУЛЕНИЕ-    = -4;    (* обнуление результата                     *)
ПЕР
  код+:ЦЕЛ;(* глоб.переменная <дМатем.код> для опознавания результата функций *)

  пГаусс:Вещ; (* память для следующего случ. числа, распределенного по Гауссу *)
  впГаусс:КЛЮЧ;                      (* ВКЛ, если <пГаусс> уже содержит число *)

(*----------------------------------------------------------------------------*
 * Математические постоянные
 *----------------------------------------------------------------------------*)
ПОСТ
  ПИ-           = 3.14159265358979323846D0; (* ПИ              *)
  ПолПИ-        = дМатем.ПИ/2;              (* ПИ пополам      *)
  ДваПИ-        = 6.28318530717958647693D0; (* 2*ПИ            *)
  Ln2-          = 0.69314718055994530942D0; (* ln(2)           *)
  Ln10-         = 2.30258509299404568402D0; (* ln(10)          *)
  LnПИ-         = 1.14472988584940017414D0; (* ln(ПИ)          *)
  КвКОРиз2-     = 1.41421356237309504880D0; (* квкор(2)        *)
  ПолКвКОРиз2-  = 0.70710678118654752440D0; (* квкор(2)/2      *)
  КвКОРиз2ПИ-   = 2.50662827463100050242D0; (* квкор(2*ПИ)     *)
  LnКвКОРиз2ПИ- = 0.91893853320467274178D0; (* ln(квкор(2*ПИ)) *)
(*
        E-      = 2.718281828459045240D0;   (*       e  *)
    Log2E-      = 1.442695040888963410D0;   (*  log2(e) *)
   Log10E-      = 0.434294481903251828D0;   (* log10(e) *)

  ЧетвертьПИ-   = дМатем.ПИ/4;              (* ПИ на 4 = Pi/4 = 0.785398163397448310; *)

    ОдинНаПИ-   = 0.318309886183790672D0;   (* 1.0 / pi *)
     ДваНаПИ-   = 0.636619772367581343D0;   (* 2.0 / pi *)

ОдинНаКвКОРизПИ-= 0.564189583547756287D0;   (* 1.0 / sqrt(pi) *)
 ДваНаКвКОРизПИ-= 1.128379167095512570D0;   (* 2.0 / sqrt(pi) *)
*)
(*----------------------------------------------------------------------------*
 * Машино-зависимые постоянные
 *----------------------------------------------------------------------------*)
ПОСТ
  МаксВещ-    =  МАКС(Вещ);
  ОбрМаксВещ- = 1/дМатем.МаксВещ;

  maxLn-  =  709.7827128933840D0;          (* максимум ln с двойной точностью *)
  minLn-  = -708.3964185322641D0;          (* минимум  ln с двойной точностью *)

  МашинEps- =  2.220446049250313D-16; (* машинный эпсилон, т.е. мин приращение
                                              или машинный 0 для вещественных *)
  МАЛОЕ-    =  1.D-20;                 (* в \Отделы\Числа\64\д\ в Матрица.отд
                                             вместо 0. с точностью 64 разряда *)


(*-оооооооооооооо- опережающие определения/заготовки задач -ооооооооооооооооо-*)


(*----------------------------------------------------------------------------*
 * Стандартные функции: мин, макс, знак числа и обмен 2-х вещ. чисел
 *----------------------------------------------------------------------------*)

ЗАДАЧА^ мин-(x,y:Вещ):Вещ;          
ЗАДАЧА^ макс-(x,y:Вещ):Вещ;          
(*
ЗАДАЧА^ минЦ-(x,y:ЦЕЛ):ЦЕЛ;
ЗАДАЧА^ максЦ-(x,y:ЦЕЛ):ЦЕЛ;          
 *)
ЗАДАЧА^ знакЧ-(x:Вещ):ЦЕЛ;     
ЗАДАЧА^ условСменаЗнакаЧ-(x,y:Вещ):Вещ;  (* x*знакЧ(y) *)
                                                  
ЗАДАЧА^ обмен-(x+,y+:Вещ);   
(*
ЗАДАЧА^ обменЦ-(x+,y+:ЦЕЛ);
 *)                                  

(*----------------------------------------------------------------------------*
 * Основные математические функции: показательные (корни и экспоненты),
 *                                  логарифмические 
 *----------------------------------------------------------------------------*)

ЗАДАЧА^ кв-(x:Вещ):Вещ;                  (* x*x *)
ЗАДАЧА^ квкор-(x:Вещ):Вещ;               (* x^0,5 *)

ЗАДАЧА^ exp-(x:Вещ):Вещ;           
ЗАДАЧА^ exp2-(x:Вещ):Вещ;  (* 2^x *)
ЗАДАЧА^ exp10-(x:Вещ):Вещ; (* 10^x *)

ЗАДАЧА^ ln-(x:Вещ):Вещ;                   
ЗАДАЧА^ log2-(x:Вещ):Вещ;  (* ln по основанию 2 *)
ЗАДАЧА^ log10-(x:Вещ):Вещ; (* десятичный логарифм *)
ЗАДАЧА^ loga-(x,a:Вещ):Вещ;(* ln по основанию a *)

(*----------------------------------------------------------------------------*
 * Степенные функции вещ. аргумента
 *----------------------------------------------------------------------------*)

ЗАДАЧА^ степВЦ-(x:Вещ; n:ЦЕЛ):Вещ;       (* x^n *)
ЗАДАЧА^ степВВ-(x,y:Вещ):Вещ;            (* x^y, x >= 0 *)

ЗАДАЧА^ Пифагор-(x,y:Вещ):Вещ;   (* квкор(x^2+y^2) *)

(*----------------------------------------------------------------------------*
 * Тригонометрические функции вещ. аргумента
 *----------------------------------------------------------------------------*)

ЗАДАЧА^ уголВПи-(тета:Вещ):Вещ;  (* угол в -ПИ..ПИ *)

ЗАДАЧА^ sin-(x:Вещ):Вещ;
ЗАДАЧА^ arcsin-(x:Вещ):Вещ;       
ЗАДАЧА^ cos-(x:Вещ):Вещ;
ЗАДАЧА^ arccos-(x:Вещ):Вещ;       
ЗАДАЧА^ sincos-(x,sinX+,cosX+:Вещ);
ЗАДАЧА^ tg-(x:Вещ):Вещ;          
ЗАДАЧА^ arctg-(x:Вещ):Вещ;
ЗАДАЧА^ arctg2-(y,x:Вещ):Вещ;    (* угол (Ox,OM) для m(x,y) *)

(*----------------------------------------------------------------------------*
 * Гиперболические функции вещ. аргумента
 *----------------------------------------------------------------------------*)

ЗАДАЧА^ sh-(x:Вещ):Вещ; 
ЗАДАЧА^ ch-(x:Вещ):Вещ; 
ЗАДАЧА^ shch-(x:Вещ; shX+,chX+:Вещ);  
ЗАДАЧА^ th-(x:Вещ):Вещ;       
ЗАДАЧА^ Arsh-(x:Вещ):Вещ;    
ЗАДАЧА^ Arch-(x:Вещ):Вещ;    
ЗАДАЧА^ Arth-(x:Вещ):Вещ;    

(*----------------------------------------------------------------------------*
 * Источники случайных вещественных чисел
 *----------------------------------------------------------------------------*)
(*
ЗАДАЧА^ случ0-(случ:ЦЕЛ);    (* выставка начального состояния *)
ЗАДАЧА^ случЦ-():ЦЕЛ;        (* целые от -2147483648 до 2147483647 *)
*)
ЗАДАЧА^ случ-():Вещ;                (* вещественные от 0 до 1  (не включая 1) *)
ЗАДАЧА^ случСГ-():Вещ;              (* вещественные, распределенные по 
                        стандартному Гауссу (мю=0,сигма=1) - нормальный закон *)
ЗАДАЧА^ случГ-(мю,сигма:Вещ):Вещ;   (* вещественные, распределенные по Гауссу *)


(*=рррррррррррррррррррррррр= реализация задач =рррррррррррррррррррррррррррррр=*)


(*============================================================================*
 * Стандартные функции: мин, макс, знак числа и обмен 2-х вещ. чисел
 *============================================================================*)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА мин-(x,y:Вещ):Вещ;
УКАЗ
  ЕСЛИ x < y ТО
    ВОЗВРАТ x
  ИНАЧЕ
    ВОЗВРАТ y
  КОН
КОН мин;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА макс-(x,y:Вещ):Вещ;
УКАЗ
  ЕСЛИ x > y ТО
    ВОЗВРАТ x
  ИНАЧЕ
    ВОЗВРАТ y
  КОН
КОН макс;
(*
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА минЦ-(x,y:ЦЕЛ):ЦЕЛ;
УКАЗ
  ЕСЛИ x < y ТО
    ВОЗВРАТ x
  ИНАЧЕ
    ВОЗВРАТ y
  КОН
КОН минЦ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА максЦ-(x,y:ЦЕЛ):ЦЕЛ;
УКАЗ
  ЕСЛИ x > y ТО
    ВОЗВРАТ x
  ИНАЧЕ
    ВОЗВРАТ y
  КОН
КОН максЦ;
*)
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА знакЧ-(x:Вещ):ЦЕЛ;
УКАЗ
  ЕСЛИ x >= 0 ТО
    ВОЗВРАТ  1
  ИНАЧЕ
    ВОЗВРАТ -1
 КОН
КОН знакЧ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА условСменаЗнакаЧ-(x,y:Вещ):Вещ;
УКАЗ
  ЕСЛИ y < 0 ТО
    ВОЗВРАТ -МОДУЛЬ(x)
  ИНАЧЕ
    ВОЗВРАТ  МОДУЛЬ(x)
  КОН
КОН условСменаЗнакаЧ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА обмен-(x+,y+:Вещ);
ПЕР
  врем:Вещ;
УКАЗ
  врем:=x;
  x:=y;
  y:=врем
КОН обмен;
(*
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА обменЦ-(x+,y+:ЦЕЛ);
ПЕР
  врем:ЦЕЛ;
УКАЗ
  врем:=x;
  x:=y;
  y:=врем
КОН обменЦ;
*)

(*============================================================================*
 * Основные математические функции: показательные (корни и экспоненты),
 *                                  логарифмические 
 *============================================================================*)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА кв-(x:Вещ):Вещ;
УКАЗ
  дМатем.код:=0;
  ВОЗВРАТ x*x
КОН кв;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА квкор-(x:Вещ):Вещ;
УКАЗ
  ЕСЛИ x < 0 ТО
    дМатем.код:=дМатем.ВНЕОБЛАСТИ;
    ВОЗВРАТ 0
  КОН;
    дМатем.код:=0;
  ВОЗВРАТ АдМ64.квкор(x)
КОН квкор;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА exp-(x:Вещ):Вещ;
УКАЗ
  ЕСЛИ x < дМатем.minLn ТО
    дМатем.код:=дМатем.ОБНУЛЕНИЕ;
    ВОЗВРАТ 0
  АЕСЛИ x > дМатем.maxLn ТО
    дМатем.код:=дМатем.ПЕРЕПОЛНЕНИЕ;
    ВОЗВРАТ дМатем.МаксВещ
  КОН;
  дМатем.код:=0;
  ВОЗВРАТ АдМ64.exp(x)
КОН exp;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА exp2-(x:Вещ):Вещ;
ПЕР
  xLn2:Вещ;
УКАЗ
  xLn2:=x*дМатем.Ln2;
  ЕСЛИ xLn2 < дМатем.minLn ТО
    дМатем.код:=дМатем.ОБНУЛЕНИЕ;
    ВОЗВРАТ 0
  АЕСЛИ xLn2 > дМатем.maxLn ТО
    дМатем.код:=дМатем.ПЕРЕПОЛНЕНИЕ;
    ВОЗВРАТ дМатем.МаксВещ
  КОН;
    дМатем.код:=0;
  ВОЗВРАТ exp(xLn2)
КОН exp2;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА exp10-(x:Вещ):Вещ;
ПЕР
  xLn10:Вещ;
УКАЗ
  xLn10:=x*Ln10;
  ЕСЛИ xLn10 < дМатем.minLn ТО
    дМатем.код:=дМатем.ОБНУЛЕНИЕ;
    ВОЗВРАТ 0
  АЕСЛИ xLn10 > дМатем.maxLn ТО
    дМатем.код:=дМатем.ПЕРЕПОЛНЕНИЕ;
    ВОЗВРАТ дМатем.МаксВещ
  КОН;
    дМатем.код:=0;
  ВОЗВРАТ exp(xLn10)
КОН exp10;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ln-(x:Вещ):Вещ;
УКАЗ
  ЕСЛИ x < 0 ТО
    дМатем.код:=дМатем.ВНЕОБЛАСТИ;
    ВОЗВРАТ -дМатем.МаксВещ
  АЕСЛИ x = 0 ТО
    дМатем.код:=дМатем.ОСОБЕННОСТЬ;
    ВОЗВРАТ -дМатем.МаксВещ
  КОН;
  дМатем.код:=0;
  ВОЗВРАТ АдМ64.ln(x)
КОН ln;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА log10-(x:Вещ):Вещ;
УКАЗ
  ЕСЛИ x < 0 ТО
    дМатем.код:=дМатем.ВНЕОБЛАСТИ;
    ВОЗВРАТ -дМатем.МаксВещ
  АЕСЛИ x = 0 ТО
    дМатем.код:=дМатем.ОСОБЕННОСТЬ;
    ВОЗВРАТ -дМатем.МаксВещ
  КОН;
  дМатем.код:=0;
  ВОЗВРАТ ln(x)/дМатем.Ln10 
КОН log10;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА log2-(x:Вещ):Вещ;
УКАЗ
  ЕСЛИ x < 0 ТО
    дМатем.код:=дМатем.ВНЕОБЛАСТИ;
    ВОЗВРАТ -дМатем.МаксВещ
  АЕСЛИ x = 0 ТО
    дМатем.код:=дМатем.ОСОБЕННОСТЬ;
    ВОЗВРАТ -дМатем.МаксВещ
  КОН;
  дМатем.код:=0;
  ВОЗВРАТ ln(x)/дМатем.Ln2
КОН log2;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА loga-(x,a:Вещ):Вещ;
ПЕР
  y:Вещ;
УКАЗ
  y:=ln(x);
  ЕСЛИ дМатем.код = 0 ТО
    ЕСЛИ a = 1 ТО
      дМатем.код:=дМатем.ОСОБЕННОСТЬ;
      y:=условСменаЗнакаЧ(дМатем.МаксВещ,y)
    ИНАЧЕ
      y:=y/ln(a)
    КОН 
  КОН;
  ВОЗВРАТ y
КОН loga;


(*============================================================================*
 * Степенные функции вещ. аргумента
 *============================================================================*)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА пробаСтеп(x,y,отв+:Вещ):КЛЮЧ;              (* локальная для дМатем.отд *)
(* Проверка случаев x=0, y=0 и y=1. В этих случаях результате x^y см. <отв+>  *)
УКАЗ
  дМатем.код:=0;
  ЕСЛИ x = 0 ТО
    ЕСЛИ y = 0 ТО     (* 0^0 = lim  x^x = 1 *)
      отв:=1          (*       x->0         *)
    АЕСЛИ y > 0 ТО
      отв:=0          (* 0^y = 0 *)
    ИНАЧЕ
      дМатем.код:=дМатем.ОСОБЕННОСТЬ;
      отв:=дМатем.МаксВещ
    КОН;
    ВОЗВРАТ ВКЛ
  АЕСЛИ y = 0 ТО
    отв:=1;           (* x^0 = 1 *)
    ВОЗВРАТ ВКЛ
  АЕСЛИ y = 1 ТО
    отв:=x;           (* x^1 = x *)
    ВОЗВРАТ ВКЛ
  ИНАЧЕ
    ВОЗВРАТ ОТКЛ
  КОН
КОН пробаСтеп;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА степВЦ-(x:Вещ; n:ЦЕЛ):Вещ;            (* целая (+/-) степень вещ.числа *)
(*
 * Вычисление  x^n  с помощью умножений, где n < 0, n > 0, n=0
 *)
ПЕР
  ответ:Вещ;
  переворот:КЛЮЧ;
УКАЗ
                                               (*-- проверка особых случаев --*)
  ЕСЛИ пробаСтеп(x,n,ответ) ТО
    ВОЗВРАТ ответ
  КОН;
                                 (*-- подготовка к вычислению целой степени --*)
  переворот:=(n < 0); 
  ЕСЛИ 1 < МОДУЛЬ(x) ТО  (* 0 ..|x| .. 1 ? *)
    x:=1/x;
    переворот:=НЕ переворот
  КОН;
                                      (*-- вычисление целой степени в цикле --*)
  ответ:=1; 
  n:=МОДУЛЬ(n);
  ПОКА 0 < n ВЫП (* при больших n это быстрее, чем последовательные умножения *)
    ЕСЛИ НЕ ЧЕТ(n) ТО
      ответ:=ответ*x
    КОН;
    x:=кв(x);                    (* x:=x*x; - затирание x *)   
    n:=n ДЕЛИТЬ 2                (* n:=n/2; - затирание n *)   
  КОН;
                         (*-- уточнение результата вычисления целой степени --*)
  ЕСЛИ переворот ТО
    ЕСЛИ МОДУЛЬ(ответ) < дМатем.ОбрМаксВещ
    ТО                                          (* только сейчас переполнение *)
      дМатем.код:=дМатем.ПЕРЕПОЛНЕНИЕ;
      ответ:=условСменаЗнакаЧ(дМатем.МаксВещ,ответ)
    ИНАЧЕ
      ответ:=1/ответ 
    КОН 
  КОН;

  ВОЗВРАТ ответ
КОН степВЦ;

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

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Пифагор-(x,y:Вещ):Вещ;
(* Вычисление квкор(x^2+y^2) без разрушения при переполнении и недополнении *)
ПЕР
  абсВел_X,
  абсВел_Y:Вещ;
УКАЗ
  дМатем.код:=0;
  абсВел_X:=МОДУЛЬ(x);
  абсВел_Y:=МОДУЛЬ(y);
  ЕСЛИ      абсВел_X > абсВел_Y ТО
    ВОЗВРАТ абсВел_X*квкор(1+кв(абсВел_Y/абсВел_X))
  АЕСЛИ     абсВел_Y = 0 ТО
    ВОЗВРАТ 0
  КОН;
        (*
  АЕСЛИ     абсВел_Y > абсВел_X
          И
        НЕ (абсВел_Y = 0)
         *)
    ВОЗВРАТ абсВел_Y*квкор(1+кв(абсВел_X/абсВел_Y))
КОН Пифагор;


(*============================================================================*
 * Тригонометрические функции вещ. аргумента
 *============================================================================*)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА уголВПи-(тета:Вещ):Вещ;
УКАЗ
  дМатем.код:=0;
  ПОКА тета >  дМатем.ПИ ВЫП
    тета:=тета-дМатем.ДваПИ 
  КОН;
  ПОКА тета <=-дМатем.ПИ ВЫП
    тета:=тета+дМатем.ДваПИ 
  КОН;
  ВОЗВРАТ тета
КОН уголВПи;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА sin-(x:Вещ):Вещ;
УКАЗ
  дМатем.код:=0;
  ВОЗВРАТ АдМ64.sin(x)
КОН sin;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА cos-(x:Вещ):Вещ;
УКАЗ
  дМатем.код:=0;
  ВОЗВРАТ АдМ64.cos(x)
КОН cos;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА sincos-(x,sinX+,cosX+:Вещ);
УКАЗ
  дМатем.код:=0;
  АдМ64.sincos(x,sinX,cosX)
КОН sincos;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА arctg-(x:Вещ):Вещ;
УКАЗ
  дМатем.код:=0;
  ВОЗВРАТ АдМ64.arctg(x)
КОН arctg;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА tg-(x:Вещ):Вещ;
ПЕР
  sinX,cosX:Вещ;
УКАЗ
  sincos(x,sinX,cosX);
  ЕСЛИ cosX = 0 ТО
    дМатем.код:=дМатем.ОСОБЕННОСТЬ;
    ВОЗВРАТ условСменаЗнакаЧ(дМатем.МаксВещ,sinX)
  КОН;
  ВОЗВРАТ sinX/cosX 
КОН tg;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА arcsin-(x:Вещ):Вещ;
ПЕР
  modX:Вещ;
УКАЗ
  modX:=МОДУЛЬ(x);
  ЕСЛИ modX > 1 ТО
    дМатем.код:=дМатем.ВНЕОБЛАСТИ;
    ВОЗВРАТ условСменаЗнакаЧ(дМатем.ПолПИ,x)
  АЕСЛИ modX = 1 ТО
    код:=0;
    ВОЗВРАТ условСменаЗнакаЧ(дМатем.ПолПИ,x)
  КОН;
  ВОЗВРАТ arctg(x/квкор(1-кв(x)))
КОН arcsin;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА arccos-(x:Вещ):Вещ;
УКАЗ
  дМатем.код:=0;
  ЕСЛИ x < -1 ТО
    дМатем.код:=дМатем.ВНЕОБЛАСТИ;
    ВОЗВРАТ дМатем.ПИ
  АЕСЛИ x > 1 ТО
    дМатем.код:=дМатем.ВНЕОБЛАСТИ;
    ВОЗВРАТ 0
  АЕСЛИ x = 1 ТО
    ВОЗВРАТ 0
  АЕСЛИ x = -1 ТО
    ВОЗВРАТ дМатем.ПИ
  КОН;
  ВОЗВРАТ дМатем.ПолПИ - arctg(x/квкор(1-кв(x)))
КОН arccos;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА arctg2-(y,x:Вещ):Вещ;
ПЕР
  тета:Вещ;
УКАЗ
  дМатем.код:=0;
  ЕСЛИ     x = 0 ТО
    ЕСЛИ     y = 0 ТО
      ВОЗВРАТ 0      (* неопределённость, т.к. 0/0 *)
    АЕСЛИ    y > 0 ТО      (*  I-й квадрант декартовой системы *)
      ВОЗВРАТ  дМатем.ПолПИ                       (* +y/0 *)
    ИНАЧЕ (* y < 0 *)      (* IV-й квадрант декартовой системы *)
      ВОЗВРАТ -дМатем.ПолПИ                       (* -y/0 *)
    КОН
  ИНАЧЕ (* x # 0 *)        (* II-III квадранты *)
        тета:=arctg(y/x);  (* -ПИ/2..ПИ/2 - пока так *)
    ЕСЛИ x < 0 ТО
      ЕСЛИ     y >= 0 ТО   (* II-й квадрант декартовой системы *)
        тета:=тета+дМатем.ПИ      (*        ПИ/2..ПИ    *)
      ИНАЧЕ (* y < 0 *)    (* III-й квадрант декартовой системы *)
        тета:=тета-дМатем.ПИ      (*         -ПИ..-ПИ/2 *)
      КОН 
    КОН;
    ВОЗВРАТ тета;
  КОН
КОН arctg2;


(*============================================================================*
 * Гиперболические функции вещ. аргумента
 *============================================================================*)

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА sh-(x:Вещ):Вещ;
ПЕР
  expX:Вещ;
УКАЗ
  ЕСЛИ (x < дМатем.minLn)
      ИЛИ
       (x > дМатем.maxLn)
  ТО
    дМатем.код:=дМатем.ПЕРЕПОЛНЕНИЕ;
    ВОЗВРАТ условСменаЗнакаЧ(дМатем.МаксВещ,x)
  КОН;
  expX:=exp(x);
  ВОЗВРАТ 0.5*(expX-1/expX)
КОН sh;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА ch-(x:Вещ):Вещ;
ПЕР
  expX:Вещ;
УКАЗ
  ЕСЛИ (x < дМатем.minLn) 
      ИЛИ 
       (x > дМатем.maxLn)
  ТО
    дМатем.код:=дМатем.ПЕРЕПОЛНЕНИЕ;
    ВОЗВРАТ дМатем.МаксВещ
  КОН;
  expX:=exp(x);
  ВОЗВРАТ 0.5*(expX+1/expX)
КОН ch;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА shch-(x:Вещ; shX+,chX+:Вещ);
ПЕР
  expX,expMinusX:Вещ;
УКАЗ
  ЕСЛИ (x < дМатем.minLn)
      ИЛИ
       (x > дМатем.maxLn)
  ТО
    дМатем.код:=дМатем.ПЕРЕПОЛНЕНИЕ;
    chX:=дМатем.МаксВещ;
    shX:=условСменаЗнакаЧ(chX,x)
  ИНАЧЕ
    expX:=exp(x);
    expMinusX:=1/expX;
    shX:=0.5*(expX-expMinusX);  (* выход *)
    chX:=0.5*(expX+expMinusX)   (* выход *)
  КОН
КОН shch;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА th-(x:Вещ):Вещ;
ПЕР
  shX,chX:Вещ;
УКАЗ
  shch(x,shX,chX);
  ВОЗВРАТ shX/chX;
КОН th;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Arsh-(x:Вещ):Вещ;
УКАЗ
  ВОЗВРАТ ln(x+квкор(кв(x)+1))
КОН Arsh;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Arch-(x:Вещ):Вещ;
УКАЗ
  ЕСЛИ x < 1 ТО
    дМатем.код:=дМатем.ВНЕОБЛАСТИ;
    ВОЗВРАТ 0
  КОН;
  ВОЗВРАТ ln(x+квкор(кв(x)-1))
КОН Arch;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА Arth-(x:Вещ):Вещ;
УКАЗ
  ЕСЛИ (x <-1) ИЛИ (x > 1) ТО
    код:=дМатем.ВНЕОБЛАСТИ;
    ВОЗВРАТ условСменаЗнакаЧ(дМатем.МаксВещ,x)
  АЕСЛИ (x =-1) ИЛИ (x = 1) ТО
    код:=дМатем.ОСОБЕННОСТЬ;
    ВОЗВРАТ условСменаЗнакаЧ(дМатем.МаксВещ,x)
  КОН;
  ВОЗВРАТ 0.5*ln((1+x)/(1-x))
КОН Arth;


(*============================================================================*
 * Источники/генераторы случайных вещ. чисел
 *============================================================================*)

(*
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА случ0-(случ:ЦЕЛ);
(* Установка/Выставка источника случайных чисел в начальное состояние *)
УКАЗ
  АцМ32.СлучНач(случ)
КОН случ0;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА случЦ-():ЦЕЛ;
(* Возвращает целые случайные числа из [-2147483648; 2147483647] *)
УКАЗ
  ВОЗВРАТ АцМ32.СлучЦел()
КОН случЦ;
*)
(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА случ-():Вещ;
(*
 * Возвращает вещественные случайные числа из [0; 1]
 *)
ПОСТ
  вминус32=1/4294967296; (* 2^-32 *)
УКАЗ
  ВОЗВРАТ АцМ32.СлучЦел()*вминус32+0.5;
КОН случ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА случСГ-():Вещ;
(* 
 * Возвращает вещественные случайные числа, распределенные по стандартному
 * Гауссу (мю=0,сигма=1) - нормальный закон
 *)
ПЕР
  r,тета,син,кос:Вещ;
УКАЗ
  ЕСЛИ НЕ впГаусс ТО                       (* впГаусс - локально в дМатем.отд *)
    r:=квкор(-2*ln(случ()));
    тета:=дМатем.ДваПИ*случ();
    sincos(тета,син,кос);
     пГаусс:=r*син;        (* сохраним    одно число *)
    впГаусс:=ВКЛ;
    ВОЗВРАТ r*кос          (* возвратим другое число *)
  КОН;
    впГаусс:=ОТКЛ;
  ВОЗВРАТ пГаусс      (* возвратим сохранённое число *)
КОН случСГ;

(*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*)
ЗАДАЧА случГ-(мю,сигма:Вещ):Вещ;
(*
 * Возвращает вещественные случайные числа, распределенные по Гауссу
 *)
УКАЗ
  ВОЗВРАТ мю+сигма*случСГ()
КОН случГ;

(*-ssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss-*)
УКАЗ
  дМатем.код:=0;                        (* дМатем.код - глобальная переменная *)
  впГаусс:=ОТКЛ;                           (* впГаусс - локально в дМатем.отд *)
(*
  цМатем.случ0(ОС.Время())        (* установка в нач.состояние генер.сл.чисел *)
*)
КОН дМатем.
