1------------------------------------------------------------------------------ 2-- -- 3-- GNAT RUN-TIME COMPONENTS -- 4-- -- 5-- M A T H _ L I B -- 6-- -- 7-- B o d y -- 8-- -- 9-- Copyright (C) 1992-2009, Free Software Foundation, Inc. -- 10-- -- 11-- GNAT is free software; you can redistribute it and/or modify it under -- 12-- terms of the GNU General Public License as published by the Free Soft- -- 13-- ware Foundation; either version 3, or (at your option) any later ver- -- 14-- sion. GNAT is distributed in the hope that it will be useful, but WITH- -- 15-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -- 16-- or FITNESS FOR A PARTICULAR PURPOSE. -- 17-- -- 18-- As a special exception under Section 7 of GPL version 3, you are granted -- 19-- additional permissions described in the GCC Runtime Library Exception, -- 20-- version 3.1, as published by the Free Software Foundation. -- 21-- -- 22-- You should have received a copy of the GNU General Public License and -- 23-- a copy of the GCC Runtime Library Exception along with this program; -- 24-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -- 25-- <http://www.gnu.org/licenses/>. -- 26-- -- 27-- GNAT was originally developed by the GNAT team at New York University. -- 28-- Extensive contributions were provided by Ada Core Technologies Inc. -- 29-- -- 30------------------------------------------------------------------------------ 31 32-- This body is specifically for using an Ada interface to C math.h to get 33-- the computation engine. Many special cases are handled locally to avoid 34-- unnecessary calls. This is not a "strict" implementation, but takes full 35-- advantage of the C functions, e.g. in providing interface to hardware 36-- provided versions of the elementary functions. 37 38-- A known weakness is that on the x86, all computation is done in Double, 39-- which means that a lot of accuracy is lost for the Long_Long_Float case. 40 41-- Uses functions sqrt, exp, log, pow, sin, asin, cos, acos, tan, atan, 42-- sinh, cosh, tanh from C library via math.h 43 44-- This is an adaptation of Ada.Numerics.Generic_Elementary_Functions that 45-- provides a compatible body for the DEC Math_Lib package. 46 47with Ada.Numerics.Aux; 48use type Ada.Numerics.Aux.Double; 49with Ada.Numerics; use Ada.Numerics; 50 51package body Math_Lib is 52 53 Log_Two : constant := 0.69314_71805_59945_30941_72321_21458_17656_80755; 54 55 Two_Pi : constant Real'Base := 2.0 * Pi; 56 Half_Pi : constant Real'Base := Pi / 2.0; 57 Fourth_Pi : constant Real'Base := Pi / 4.0; 58 Epsilon : constant Real'Base := Real'Base'Epsilon; 59 IEpsilon : constant Real'Base := 1.0 / Epsilon; 60 61 subtype Double is Aux.Double; 62 63 DEpsilon : constant Double := Double (Epsilon); 64 DIEpsilon : constant Double := Double (IEpsilon); 65 66 ----------------------- 67 -- Local Subprograms -- 68 ----------------------- 69 70 function Arctan 71 (Y : Real; 72 A : Real := 1.0) 73 return Real; 74 75 function Arctan 76 (Y : Real; 77 A : Real := 1.0; 78 Cycle : Real) 79 return Real; 80 81 function Exact_Remainder 82 (A : Real; 83 Y : Real) 84 return Real; 85 -- Computes exact remainder of A divided by Y 86 87 function Half_Log_Epsilon return Real; 88 -- Function to provide constant: 0.5 * Log (Epsilon) 89 90 function Local_Atan 91 (Y : Real; 92 A : Real := 1.0) 93 return Real; 94 -- Common code for arc tangent after cycle reduction 95 96 function Log_Inverse_Epsilon return Real; 97 -- Function to provide constant: Log (1.0 / Epsilon) 98 99 function Square_Root_Epsilon return Real; 100 -- Function to provide constant: Sqrt (Epsilon) 101 102 ---------- 103 -- "**" -- 104 ---------- 105 106 function "**" (A1, A2 : Real) return Real is 107 108 begin 109 if A1 = 0.0 110 and then A2 = 0.0 111 then 112 raise Argument_Error; 113 114 elsif A1 < 0.0 then 115 raise Argument_Error; 116 117 elsif A2 = 0.0 then 118 return 1.0; 119 120 elsif A1 = 0.0 then 121 if A2 < 0.0 then 122 raise Constraint_Error; 123 else 124 return 0.0; 125 end if; 126 127 elsif A1 = 1.0 then 128 return 1.0; 129 130 elsif A2 = 1.0 then 131 return A1; 132 133 else 134 begin 135 if A2 = 2.0 then 136 return A1 * A1; 137 else 138 return 139 Real (Aux.pow (Double (A1), Double (A2))); 140 end if; 141 142 exception 143 when others => 144 raise Constraint_Error; 145 end; 146 end if; 147 end "**"; 148 149 ------------ 150 -- Arccos -- 151 ------------ 152 153 -- Natural cycle 154 155 function Arccos (A : Real) return Real is 156 Temp : Real'Base; 157 158 begin 159 if abs A > 1.0 then 160 raise Argument_Error; 161 162 elsif abs A < Square_Root_Epsilon then 163 return Pi / 2.0 - A; 164 165 elsif A = 1.0 then 166 return 0.0; 167 168 elsif A = -1.0 then 169 return Pi; 170 end if; 171 172 Temp := Real (Aux.acos (Double (A))); 173 174 if Temp < 0.0 then 175 Temp := Pi + Temp; 176 end if; 177 178 return Temp; 179 end Arccos; 180 181 -- Arbitrary cycle 182 183 function Arccos (A, Cycle : Real) return Real is 184 Temp : Real'Base; 185 186 begin 187 if Cycle <= 0.0 then 188 raise Argument_Error; 189 190 elsif abs A > 1.0 then 191 raise Argument_Error; 192 193 elsif abs A < Square_Root_Epsilon then 194 return Cycle / 4.0; 195 196 elsif A = 1.0 then 197 return 0.0; 198 199 elsif A = -1.0 then 200 return Cycle / 2.0; 201 end if; 202 203 Temp := Arctan (Sqrt (1.0 - A * A) / A, 1.0, Cycle); 204 205 if Temp < 0.0 then 206 Temp := Cycle / 2.0 + Temp; 207 end if; 208 209 return Temp; 210 end Arccos; 211 212 ------------- 213 -- Arccosh -- 214 ------------- 215 216 function Arccosh (A : Real) return Real is 217 begin 218 -- Return Log (A - Sqrt (A * A - 1.0)); double valued, 219 -- only positive value returned 220 -- What is this comment ??? 221 222 if A < 1.0 then 223 raise Argument_Error; 224 225 elsif A < 1.0 + Square_Root_Epsilon then 226 return A - 1.0; 227 228 elsif abs A > 1.0 / Square_Root_Epsilon then 229 return Log (A) + Log_Two; 230 231 else 232 return Log (A + Sqrt (A * A - 1.0)); 233 end if; 234 end Arccosh; 235 236 ------------ 237 -- Arccot -- 238 ------------ 239 240 -- Natural cycle 241 242 function Arccot 243 (A : Real; 244 Y : Real := 1.0) 245 return Real 246 is 247 begin 248 -- Just reverse arguments 249 250 return Arctan (Y, A); 251 end Arccot; 252 253 -- Arbitrary cycle 254 255 function Arccot 256 (A : Real; 257 Y : Real := 1.0; 258 Cycle : Real) 259 return Real 260 is 261 begin 262 -- Just reverse arguments 263 264 return Arctan (Y, A, Cycle); 265 end Arccot; 266 267 ------------- 268 -- Arccoth -- 269 ------------- 270 271 function Arccoth (A : Real) return Real is 272 begin 273 if abs A = 1.0 then 274 raise Constraint_Error; 275 276 elsif abs A < 1.0 then 277 raise Argument_Error; 278 279 elsif abs A > 1.0 / Epsilon then 280 return 0.0; 281 282 else 283 return 0.5 * Log ((1.0 + A) / (A - 1.0)); 284 end if; 285 end Arccoth; 286 287 ------------ 288 -- Arcsin -- 289 ------------ 290 291 -- Natural cycle 292 293 function Arcsin (A : Real) return Real is 294 begin 295 if abs A > 1.0 then 296 raise Argument_Error; 297 298 elsif abs A < Square_Root_Epsilon then 299 return A; 300 301 elsif A = 1.0 then 302 return Pi / 2.0; 303 304 elsif A = -1.0 then 305 return -Pi / 2.0; 306 end if; 307 308 return Real (Aux.asin (Double (A))); 309 end Arcsin; 310 311 -- Arbitrary cycle 312 313 function Arcsin (A, Cycle : Real) return Real is 314 begin 315 if Cycle <= 0.0 then 316 raise Argument_Error; 317 318 elsif abs A > 1.0 then 319 raise Argument_Error; 320 321 elsif A = 0.0 then 322 return A; 323 324 elsif A = 1.0 then 325 return Cycle / 4.0; 326 327 elsif A = -1.0 then 328 return -Cycle / 4.0; 329 end if; 330 331 return Arctan (A / Sqrt (1.0 - A * A), 1.0, Cycle); 332 end Arcsin; 333 334 ------------- 335 -- Arcsinh -- 336 ------------- 337 338 function Arcsinh (A : Real) return Real is 339 begin 340 if abs A < Square_Root_Epsilon then 341 return A; 342 343 elsif A > 1.0 / Square_Root_Epsilon then 344 return Log (A) + Log_Two; 345 346 elsif A < -1.0 / Square_Root_Epsilon then 347 return -(Log (-A) + Log_Two); 348 349 elsif A < 0.0 then 350 return -Log (abs A + Sqrt (A * A + 1.0)); 351 352 else 353 return Log (A + Sqrt (A * A + 1.0)); 354 end if; 355 end Arcsinh; 356 357 ------------ 358 -- Arctan -- 359 ------------ 360 361 -- Natural cycle 362 363 function Arctan 364 (Y : Real; 365 A : Real := 1.0) 366 return Real 367 is 368 begin 369 if A = 0.0 370 and then Y = 0.0 371 then 372 raise Argument_Error; 373 374 elsif Y = 0.0 then 375 if A > 0.0 then 376 return 0.0; 377 else -- A < 0.0 378 return Pi; 379 end if; 380 381 elsif A = 0.0 then 382 if Y > 0.0 then 383 return Half_Pi; 384 else -- Y < 0.0 385 return -Half_Pi; 386 end if; 387 388 else 389 return Local_Atan (Y, A); 390 end if; 391 end Arctan; 392 393 -- Arbitrary cycle 394 395 function Arctan 396 (Y : Real; 397 A : Real := 1.0; 398 Cycle : Real) 399 return Real 400 is 401 begin 402 if Cycle <= 0.0 then 403 raise Argument_Error; 404 405 elsif A = 0.0 406 and then Y = 0.0 407 then 408 raise Argument_Error; 409 410 elsif Y = 0.0 then 411 if A > 0.0 then 412 return 0.0; 413 else -- A < 0.0 414 return Cycle / 2.0; 415 end if; 416 417 elsif A = 0.0 then 418 if Y > 0.0 then 419 return Cycle / 4.0; 420 else -- Y < 0.0 421 return -Cycle / 4.0; 422 end if; 423 424 else 425 return Local_Atan (Y, A) * Cycle / Two_Pi; 426 end if; 427 end Arctan; 428 429 ------------- 430 -- Arctanh -- 431 ------------- 432 433 function Arctanh (A : Real) return Real is 434 begin 435 if abs A = 1.0 then 436 raise Constraint_Error; 437 438 elsif abs A > 1.0 then 439 raise Argument_Error; 440 441 elsif abs A < Square_Root_Epsilon then 442 return A; 443 444 else 445 return 0.5 * Log ((1.0 + A) / (1.0 - A)); 446 end if; 447 end Arctanh; 448 449 --------- 450 -- Cos -- 451 --------- 452 453 -- Natural cycle 454 455 function Cos (A : Real) return Real is 456 begin 457 if A = 0.0 then 458 return 1.0; 459 460 elsif abs A < Square_Root_Epsilon then 461 return 1.0; 462 463 end if; 464 465 return Real (Aux.Cos (Double (A))); 466 end Cos; 467 468 -- Arbitrary cycle 469 470 function Cos (A, Cycle : Real) return Real is 471 T : Real'Base; 472 473 begin 474 if Cycle <= 0.0 then 475 raise Argument_Error; 476 477 elsif A = 0.0 then 478 return 1.0; 479 end if; 480 481 T := Exact_Remainder (abs (A), Cycle) / Cycle; 482 483 if T = 0.25 484 or else T = 0.75 485 or else T = -0.25 486 or else T = -0.75 487 then 488 return 0.0; 489 490 elsif T = 0.5 or T = -0.5 then 491 return -1.0; 492 end if; 493 494 return Real (Aux.Cos (Double (T * Two_Pi))); 495 end Cos; 496 497 ---------- 498 -- Cosh -- 499 ---------- 500 501 function Cosh (A : Real) return Real is 502 begin 503 if abs A < Square_Root_Epsilon then 504 return 1.0; 505 506 elsif abs A > Log_Inverse_Epsilon then 507 return Exp ((abs A) - Log_Two); 508 end if; 509 510 return Real (Aux.cosh (Double (A))); 511 512 exception 513 when others => 514 raise Constraint_Error; 515 end Cosh; 516 517 --------- 518 -- Cot -- 519 --------- 520 521 -- Natural cycle 522 523 function Cot (A : Real) return Real is 524 begin 525 if A = 0.0 then 526 raise Constraint_Error; 527 528 elsif abs A < Square_Root_Epsilon then 529 return 1.0 / A; 530 end if; 531 532 return Real (1.0 / Real'Base (Aux.tan (Double (A)))); 533 end Cot; 534 535 -- Arbitrary cycle 536 537 function Cot (A, Cycle : Real) return Real is 538 T : Real'Base; 539 540 begin 541 if Cycle <= 0.0 then 542 raise Argument_Error; 543 544 elsif A = 0.0 then 545 raise Constraint_Error; 546 547 elsif abs A < Square_Root_Epsilon then 548 return 1.0 / A; 549 end if; 550 551 T := Exact_Remainder (A, Cycle) / Cycle; 552 553 if T = 0.0 or T = 0.5 or T = -0.5 then 554 raise Constraint_Error; 555 else 556 return Cos (T * Two_Pi) / Sin (T * Two_Pi); 557 end if; 558 end Cot; 559 560 ---------- 561 -- Coth -- 562 ---------- 563 564 function Coth (A : Real) return Real is 565 begin 566 if A = 0.0 then 567 raise Constraint_Error; 568 569 elsif A < Half_Log_Epsilon then 570 return -1.0; 571 572 elsif A > -Half_Log_Epsilon then 573 return 1.0; 574 575 elsif abs A < Square_Root_Epsilon then 576 return 1.0 / A; 577 end if; 578 579 return Real (1.0 / Real'Base (Aux.tanh (Double (A)))); 580 end Coth; 581 582 --------------------- 583 -- Exact_Remainder -- 584 --------------------- 585 586 function Exact_Remainder 587 (A : Real; 588 Y : Real) 589 return Real 590 is 591 Denominator : Real'Base := abs A; 592 Divisor : Real'Base := abs Y; 593 Reducer : Real'Base; 594 Sign : Real'Base := 1.0; 595 596 begin 597 if Y = 0.0 then 598 raise Constraint_Error; 599 600 elsif A = 0.0 then 601 return 0.0; 602 603 elsif A = Y then 604 return 0.0; 605 606 elsif Denominator < Divisor then 607 return A; 608 end if; 609 610 while Denominator >= Divisor loop 611 612 -- Put divisors mantissa with denominators exponent to make reducer 613 614 Reducer := Divisor; 615 616 begin 617 while Reducer * 1_048_576.0 < Denominator loop 618 Reducer := Reducer * 1_048_576.0; 619 end loop; 620 621 exception 622 when others => null; 623 end; 624 625 begin 626 while Reducer * 1_024.0 < Denominator loop 627 Reducer := Reducer * 1_024.0; 628 end loop; 629 630 exception 631 when others => null; 632 end; 633 634 begin 635 while Reducer * 2.0 < Denominator loop 636 Reducer := Reducer * 2.0; 637 end loop; 638 639 exception 640 when others => null; 641 end; 642 643 Denominator := Denominator - Reducer; 644 end loop; 645 646 if A < 0.0 then 647 return -Denominator; 648 else 649 return Denominator; 650 end if; 651 end Exact_Remainder; 652 653 --------- 654 -- Exp -- 655 --------- 656 657 function Exp (A : Real) return Real is 658 Result : Real'Base; 659 660 begin 661 if A = 0.0 then 662 return 1.0; 663 664 else 665 Result := Real (Aux.Exp (Double (A))); 666 667 -- The check here catches the case of Exp returning IEEE infinity 668 669 if Result > Real'Last then 670 raise Constraint_Error; 671 else 672 return Result; 673 end if; 674 end if; 675 end Exp; 676 677 ---------------------- 678 -- Half_Log_Epsilon -- 679 ---------------------- 680 681 -- Cannot precompute this constant, because this is required to be a 682 -- pure package, which allows no state. A pity, but no way around it! 683 684 function Half_Log_Epsilon return Real is 685 begin 686 return Real (0.5 * Real'Base (Aux.Log (DEpsilon))); 687 end Half_Log_Epsilon; 688 689 ---------------- 690 -- Local_Atan -- 691 ---------------- 692 693 function Local_Atan 694 (Y : Real; 695 A : Real := 1.0) 696 return Real 697 is 698 Z : Real'Base; 699 Raw_Atan : Real'Base; 700 701 begin 702 if abs Y > abs A then 703 Z := abs (A / Y); 704 else 705 Z := abs (Y / A); 706 end if; 707 708 if Z < Square_Root_Epsilon then 709 Raw_Atan := Z; 710 711 elsif Z = 1.0 then 712 Raw_Atan := Pi / 4.0; 713 714 elsif Z < Square_Root_Epsilon then 715 Raw_Atan := Z; 716 717 else 718 Raw_Atan := Real'Base (Aux.Atan (Double (Z))); 719 end if; 720 721 if abs Y > abs A then 722 Raw_Atan := Half_Pi - Raw_Atan; 723 end if; 724 725 if A > 0.0 then 726 if Y > 0.0 then 727 return Raw_Atan; 728 else -- Y < 0.0 729 return -Raw_Atan; 730 end if; 731 732 else -- A < 0.0 733 if Y > 0.0 then 734 return Pi - Raw_Atan; 735 else -- Y < 0.0 736 return -(Pi - Raw_Atan); 737 end if; 738 end if; 739 end Local_Atan; 740 741 --------- 742 -- Log -- 743 --------- 744 745 -- Natural base 746 747 function Log (A : Real) return Real is 748 begin 749 if A < 0.0 then 750 raise Argument_Error; 751 752 elsif A = 0.0 then 753 raise Constraint_Error; 754 755 elsif A = 1.0 then 756 return 0.0; 757 end if; 758 759 return Real (Aux.Log (Double (A))); 760 end Log; 761 762 -- Arbitrary base 763 764 function Log (A, Base : Real) return Real is 765 begin 766 if A < 0.0 then 767 raise Argument_Error; 768 769 elsif Base <= 0.0 or else Base = 1.0 then 770 raise Argument_Error; 771 772 elsif A = 0.0 then 773 raise Constraint_Error; 774 775 elsif A = 1.0 then 776 return 0.0; 777 end if; 778 779 return Real (Aux.Log (Double (A)) / Aux.Log (Double (Base))); 780 end Log; 781 782 ------------------------- 783 -- Log_Inverse_Epsilon -- 784 ------------------------- 785 786 -- Cannot precompute this constant, because this is required to be a 787 -- pure package, which allows no state. A pity, but no way around it! 788 789 function Log_Inverse_Epsilon return Real is 790 begin 791 return Real (Aux.Log (DIEpsilon)); 792 end Log_Inverse_Epsilon; 793 794 --------- 795 -- Sin -- 796 --------- 797 798 -- Natural cycle 799 800 function Sin (A : Real) return Real is 801 begin 802 if abs A < Square_Root_Epsilon then 803 return A; 804 end if; 805 806 return Real (Aux.Sin (Double (A))); 807 end Sin; 808 809 -- Arbitrary cycle 810 811 function Sin (A, Cycle : Real) return Real is 812 T : Real'Base; 813 814 begin 815 if Cycle <= 0.0 then 816 raise Argument_Error; 817 818 elsif A = 0.0 then 819 return A; 820 end if; 821 822 T := Exact_Remainder (A, Cycle) / Cycle; 823 824 if T = 0.0 or T = 0.5 or T = -0.5 then 825 return 0.0; 826 827 elsif T = 0.25 or T = -0.75 then 828 return 1.0; 829 830 elsif T = -0.25 or T = 0.75 then 831 return -1.0; 832 833 end if; 834 835 return Real (Aux.Sin (Double (T * Two_Pi))); 836 end Sin; 837 838 ---------- 839 -- Sinh -- 840 ---------- 841 842 function Sinh (A : Real) return Real is 843 begin 844 if abs A < Square_Root_Epsilon then 845 return A; 846 847 elsif A > Log_Inverse_Epsilon then 848 return Exp (A - Log_Two); 849 850 elsif A < -Log_Inverse_Epsilon then 851 return -Exp ((-A) - Log_Two); 852 end if; 853 854 return Real (Aux.Sinh (Double (A))); 855 856 exception 857 when others => 858 raise Constraint_Error; 859 end Sinh; 860 861 ------------------------- 862 -- Square_Root_Epsilon -- 863 ------------------------- 864 865 -- Cannot precompute this constant, because this is required to be a 866 -- pure package, which allows no state. A pity, but no way around it! 867 868 function Square_Root_Epsilon return Real is 869 begin 870 return Real (Aux.Sqrt (DEpsilon)); 871 end Square_Root_Epsilon; 872 873 ---------- 874 -- Sqrt -- 875 ---------- 876 877 function Sqrt (A : Real) return Real is 878 begin 879 if A < 0.0 then 880 raise Argument_Error; 881 882 -- Special case Sqrt (0.0) to preserve possible minus sign per IEEE 883 884 elsif A = 0.0 then 885 return A; 886 887 -- Sqrt (1.0) must be exact for good complex accuracy 888 889 elsif A = 1.0 then 890 return 1.0; 891 892 end if; 893 894 return Real (Aux.Sqrt (Double (A))); 895 end Sqrt; 896 897 --------- 898 -- Tan -- 899 --------- 900 901 -- Natural cycle 902 903 function Tan (A : Real) return Real is 904 begin 905 if abs A < Square_Root_Epsilon then 906 return A; 907 908 elsif abs A = Pi / 2.0 then 909 raise Constraint_Error; 910 end if; 911 912 return Real (Aux.tan (Double (A))); 913 end Tan; 914 915 -- Arbitrary cycle 916 917 function Tan (A, Cycle : Real) return Real is 918 T : Real'Base; 919 920 begin 921 if Cycle <= 0.0 then 922 raise Argument_Error; 923 924 elsif A = 0.0 then 925 return A; 926 end if; 927 928 T := Exact_Remainder (A, Cycle) / Cycle; 929 930 if T = 0.25 931 or else T = 0.75 932 or else T = -0.25 933 or else T = -0.75 934 then 935 raise Constraint_Error; 936 937 else 938 return Sin (T * Two_Pi) / Cos (T * Two_Pi); 939 end if; 940 end Tan; 941 942 ---------- 943 -- Tanh -- 944 ---------- 945 946 function Tanh (A : Real) return Real is 947 begin 948 if A < Half_Log_Epsilon then 949 return -1.0; 950 951 elsif A > -Half_Log_Epsilon then 952 return 1.0; 953 954 elsif abs A < Square_Root_Epsilon then 955 return A; 956 end if; 957 958 return Real (Aux.tanh (Double (A))); 959 end Tanh; 960 961 ---------------------------- 962 -- DEC-Specific functions -- 963 ---------------------------- 964 965 function LOG10 (A : REAL) return REAL is 966 begin 967 return Log (A, 10.0); 968 end LOG10; 969 970 function LOG2 (A : REAL) return REAL is 971 begin 972 return Log (A, 2.0); 973 end LOG2; 974 975 function ASIN (A : REAL) return REAL renames Arcsin; 976 function ACOS (A : REAL) return REAL renames Arccos; 977 978 function ATAN (A : REAL) return REAL is 979 begin 980 return Arctan (A, 1.0); 981 end ATAN; 982 983 function ATAN2 (A1, A2 : REAL) return REAL renames Arctan; 984 985 function SIND (A : REAL) return REAL is 986 begin 987 return Sin (A, 360.0); 988 end SIND; 989 990 function COSD (A : REAL) return REAL is 991 begin 992 return Cos (A, 360.0); 993 end COSD; 994 995 function TAND (A : REAL) return REAL is 996 begin 997 return Tan (A, 360.0); 998 end TAND; 999 1000 function ASIND (A : REAL) return REAL is 1001 begin 1002 return Arcsin (A, 360.0); 1003 end ASIND; 1004 1005 function ACOSD (A : REAL) return REAL is 1006 begin 1007 return Arccos (A, 360.0); 1008 end ACOSD; 1009 1010 function Arctan (A : REAL) return REAL is 1011 begin 1012 return Arctan (A, 1.0, 360.0); 1013 end Arctan; 1014 1015 function ATAND (A : REAL) return REAL is 1016 begin 1017 return Arctan (A, 1.0, 360.0); 1018 end ATAND; 1019 1020 function ATAN2D (A1, A2 : REAL) return REAL is 1021 begin 1022 return Arctan (A1, A2, 360.0); 1023 end ATAN2D; 1024 1025end Math_Lib; 1026