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