17.14. Elementární (matematické) funkce Jazyk MX COBOL umožňuje provádět v cobolském programu výpočet všech základních elementárních funkcí. Způsob volání (pro všechny realizované elementární funkce): CALL 'jméno' USING argument příjmová V tomto formátu "jméno" znamená jméno podprogramu uvedené v prvním sloupci následující tabulky (ve skutečnosti ovšem podprogramy s těmito jmény neexistují a nejsou dodávány, příkaz CALL se překládá voláním odpovídající systémové funkce), "argument" znamená vstupní argument elementární funkce (musí to být numerická položka libovolného typu nebo numerický literál), "příjmová" znamená příjmovou položku, do níž bude dosazena hodnota výsledku příslušné elementární funkce (musí to být numerická položka libovolného typu). Jsou realizovány tyto elementární funkce: jméno funkce v jazyce C význam ------------------------------------------------------------ ICLN log(x) přirozený logaritmus o základu e=2.71828.. ICFLOG log(x) přirozený logaritmus o základu e=2.71828.. ICFLOG10 log10(x) dekadický logaritmus o základu 10 ICFEXP exp(x) e ** x; základem mocniny je e=2.71828... ICFSQRT sqrt(x) druhá odmocnina ICSIN sin(x) sinus; argument se zadává v radiánech ICFSIN sin(x) sinus; argument se zadává v radiánech ICCOS cos(x) kosinus; argument se zadává v radiánech ICFCOS cos(x) kosinus; argument se zadává v radiánech ICFTAN tan(x) tangens; argument se zadává v radiánech ICFCOTAN 1./tan(x) kotangens; argument se zadává v radiánech ICARCSIN asin(x) arkussinus; výsledek je v radiánech ICFARSIN asin(x) arkussinus; výsledek je v radiánech ICFARCOS acos(x) arkuskosinus; výsledek je v radiánech ICARCTG atan(x) arkustangens; výsledek je v radiánech ICFATAN atan(x) arkustangens; výsledek je v radiánech ICFSINH sinh(x) hyperbolický sinus ICFCOSH cosh(x) hyperbolický kosinus ICFTANH tanh(x) hyperbolický tangens ICFERF erf(x) tzv. chybová funkce (viz manuál jazyka C) ICFERFC erfc(x) erfc(x) = 1.0 - erf(x) ICFABS fabs(x) absolutní hodnota pro typ "double" ICFLOOR floor(x) největší celé číslo,které není větší než x ICFCEIL ceil(x) nejmenší celé číslo,které není menší než x ICFJ0 j0(x) Besselova funkce prvního druhu řádu 0 ICFJ1 j1(x) Besselova funkce prvního druhu řádu 1 ICFY0 y0(x) Besselova funkce druhého druhu řádu 0 ICFY1 y1(x) Besselova funkce druhého druhu řádu 1 ICFGAMMA exp(gamma(x))*signgam hodnota funkce gama ICFLGAMA gamma(x) přirozený logaritmus hodnoty funkce gama Výpočet výše uvedených elementárních funkcí má sice obvyklý formát příkazu CALL, nicméně překladač jazyka MX COBOL rozpozná, že za slovem CALL je uvedeno některé ze jmen z prvního sloupce tabulky, a překládá pak tento příkaz CALL speciálním způsobem. Např. příkaz CALL 'ICFSIN' USING ALFA BETA vlastně převede na příkaz jazyka C BETA=sin(ALFA); Činnost příkazu CALL přitom spočívá v těchto krocích: 1) Není-li argument funkce exponenciální dlouhou položkou ani literálem, bude nejprve přesunut do pomocné exponenciální dlouhé položky dle pravidel příkazu MOVE. Numerický literál je ovšem převeden do exponenciálního dlouhého tvaru již během překladu. 2) Bude vyvolána vhodná funkce jazyka C (její jméno je uvedeno ve druhém sloupci tabulky) a bude jí předán argument funkce převedený do exponenciálního dlouhého tvaru. Tato funkce vrátí hodnotu výsledku příslušné elementární funkce opět v exponenciálním dlouhém tvaru. 3) Tato hodnota výsledku bude přesunuta do příjmové položky dle pravidel příkazu MOVE. Poznámky: 1) Na hodnoty vstupních argumentů jednotlivých funkcí jsou kladeny obvyklé požadavky (tzn. argument pro ICLN, ICFLOG a ICFLOG10 musí být kladný, argument pro ICARCSIN, ICFARSIN a ICFARCOS musí být v absolutní hodnotě nejvýše roven jedné atd.). Přesné formulace těchto požadavků, průběh při jejich porušení, přesnost výsledku atd. je třeba hledat v dokumentaci jazyka C. 2) Jména ICSIN a ICFSIN jsou přesně ekvivalentní (kvůli kompatibilitě s COBOLem MOS a s COBOLem DOS-3 jsou povoleny obě možnosti). Podobně jsou ekvivalentní jména ICCOS a ICFCOS, ICLN a ICFLOG, ICARCSIN a ICFARSIN, ICARCTG a ICFATAN. 3) Podprogramy ICFABS, ICFLOOR a ICFCEIL jsou výhodné pouze v případě, že argument funkce i příjmová položka jsou v exponenciálním tvaru. U argumentů v dekadickém tvaru by jejich použití zahrnovalo zbytečný převod argumentu do exponenciálního dlouhého tvaru a zpětný převod výsledku z exponenciálního dlouhého tvaru do dekadického tvaru, ačkoliv lze touž akci snadno vyjádřit cobolskými prostředky (absolutní hodnotu získáme přesunem do položky bez znaku S v PICTURE, "floor" získáme při nezáporné hodnotě přesunem do celočíselné položky, "ceil" získáme při nezáporné hodnotě přičtením konstanty typu 0.999 a přesunem do celočíselné položky. Příklady: CALL 'ICSIN' USING X Y CALL 'ICFCOS' USING -.543 KONST CALL 'ICLN' USING ARGUMENT VYSLEDEK CALL 'ICFLOG10' USING 2 POMOC CALL 'ICARCSIN' USING X(I J K) ARX(I J K) CALL 'ICFSINH' USING A OF PRVNI A OF DRUHA (N) CALL 'ICFGAMMA' USING 2.8 GAM Příklad: Je-li argument pro funkci sinus, kosinus, tangens nebo kotangens zadán ve stupních, je nutno jej před vyvoláním podprogramu nejprve převést do obloukové míry (na radiány), to jest vynásobit počet stupňů číslem ă / 180 = 0.01745329251994329576923690757... Je-li argument zadán dokonce pomocí tří položek udávajících stupně, úhlové minuty a úhlové vteřiny, je nutno ještě před tímto násobením všechny tyto údaje převést na stupně a sečíst: 77 STUPNE PIC S999 COMP. 77 MINUTY PIC S99 COMP. 77 VTERINY PIC S99V99 COMP. 77 RADIANY COMP-2. 77 VYSLEDEK PIC S9V9(9) COMP. : COMPUTE RADIANY = (STUPNE + MINUTY / 60 + VTERINY / 3600) * 0.01745329251994329577. CALL 'ICFSIN' USING RADIANY VYSLEDEK. Příklad: Obráceně, chceme-li získat hodnotu funkce arkussinus, arkuskosinus nebo arkustangens ve stupních (případně dokonce ve stupních, minutách a vteřinách), je nutno po vyvolání podprogramu převést výsledek z radiánů na stupně, to jest vynásobit počet radiánů číslem 180 / ă = 57.2957795130823... 77 ARGUMENT PIC S9V9(8) COMP. 77 RADIANY COMP-2. 77 STUP PIC S999V9(6) COMP. 77 STUPNE PIC S999 COMP. 77 MINUTY PIC S99 COMP. 77 VTERINY PIC S99V99 COMP. : CALL 'ICFARSIN' USING ARGUMENT RADIANY. COMPUTE STUP = RADIANY * 57.2957795130823. MOVE STUP TO STUPNE. COMPUTE STUP = (STUP - STUPNE) * 60. MOVE STUP TO MINUTY. COMPUTE VTERINY ROUNDED = (STUP - MINUTY) * 60. Příklad: MX COBOL umožňuje volání právě všech funkcí jazyka C, jejichž prototypy jsou obsaženy v souboru , pokud mají jediný parametr typu "double" a vracejí hodnotu typu "double". Volání kterékoliv jiné funkce může uživatel snadno zařídit pomocí příkazu UFO. Tak např. volání funkce jn(n,x) (Besselova funkce prvního druhu řádu n), která má dva argumenty, první typu "int" a druhý typu "double" a vrací hodnotu typu "double", lze zařadit příkazem UFO ***VYSLEDEK '=jn((int)' *N ',' ***X ');' #0A# kde VYSLEDEK musí být exponenciální dlouhá položka a N a X mohou být libovolné numerické položky (pokud by N byla celočíselná numerická položka s nejvýše 4 devítkami v PICTURE, je "(int)" nadbytečné). Je-li v témže zdrojovém programu uvedeno volání alespoň jedné elementární funkce z výše uvedené tabulky, bude cílový C-program obsahovat i celý soubor math.h (#include ), tedy i prototyp funkce jn. Jinak by musel uživatel zajistit zařazení tohoto prototypu explicitně, a to buďto příkazem UFD 'extern double jn(int,double);' #0A# nebo příkazem UFD '#include ' #0A#.