1 /** 2 * D header file for C99. 3 * 4 * $(C_HEADER_DESCRIPTION pubs.opengroup.org/onlinepubs/009695399/basedefs/_fenv.h.html, _fenv.h) 5 * 6 * Copyright: Copyright Sean Kelly 2005 - 2009. 7 * License: Distributed under the 8 * $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0). 9 * (See accompanying file LICENSE) 10 * Authors: Sean Kelly 11 * Source: $(DRUNTIMESRC core/stdc/_fenv.d) 12 * Standards: ISO/IEC 9899:1999 (E) 13 */ 14 15 module core.stdc.fenv; 16 17 version (CRuntime_LIBWASM) {} else: // not implemented 18 19 version (OSX) 20 version = Darwin; 21 else version (iOS) 22 version = Darwin; 23 else version (TVOS) 24 version = Darwin; 25 else version (WatchOS) 26 version = Darwin; 27 28 extern (C): 29 nothrow: 30 @nogc: 31 32 version (ARM) version = ARM_Any; 33 version (AArch64) version = ARM_Any; 34 version (HPPA) version = HPPA_Any; 35 version (MIPS32) version = MIPS_Any; 36 version (MIPS64) version = MIPS_Any; 37 version (PPC) version = PPC_Any; 38 version (PPC64) version = PPC_Any; 39 version (RISCV32) version = RISCV_Any; 40 version (RISCV64) version = RISCV_Any; 41 version (S390) version = IBMZ_Any; 42 version (SPARC) version = SPARC_Any; 43 version (SPARC64) version = SPARC_Any; 44 version (SystemZ) version = IBMZ_Any; 45 version (X86) version = X86_Any; 46 version (X86_64) version = X86_Any; 47 48 version (MinGW) 49 version = GNUFP; 50 version (CRuntime_Glibc) 51 version = GNUFP; 52 53 version (GNUFP) 54 { 55 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h 56 version (X86) 57 { 58 struct fenv_t 59 { 60 ushort __control_word; 61 ushort __unused1; 62 ushort __status_word; 63 ushort __unused2; 64 ushort __tags; 65 ushort __unused3; 66 uint __eip; 67 ushort __cs_selector; 68 ushort __opcode; 69 uint __data_offset; 70 ushort __data_selector; 71 ushort __unused5; 72 } 73 74 alias fexcept_t = ushort; 75 } 76 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86/fpu/bits/fenv.h 77 else version (X86_64) 78 { 79 struct fenv_t 80 { 81 ushort __control_word; 82 ushort __unused1; 83 ushort __status_word; 84 ushort __unused2; 85 ushort __tags; 86 ushort __unused3; 87 uint __eip; 88 ushort __cs_selector; 89 ushort __opcode; 90 uint __data_offset; 91 ushort __data_selector; 92 ushort __unused5; 93 uint __mxcsr; 94 } 95 96 alias fexcept_t = ushort; 97 } 98 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/hppa/bits/fenv.h 99 else version (HPPA_Any) 100 { 101 struct fenv_t 102 { 103 uint __status_word; 104 uint[7] __exception; 105 } 106 107 alias fexcept_t = uint; 108 } 109 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/mips/bits/fenv.h 110 else version (MIPS_Any) 111 { 112 struct fenv_t 113 { 114 uint __fp_control_register; 115 } 116 117 alias fexcept_t = ushort; 118 } 119 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/aarch64/bits/fenv.h 120 else version (AArch64) 121 { 122 struct fenv_t 123 { 124 uint __fpcr; 125 uint __fpsr; 126 } 127 128 alias fexcept_t = uint; 129 } 130 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/bits/fenv.h 131 else version (ARM) 132 { 133 struct fenv_t 134 { 135 uint __cw; 136 } 137 138 alias fexcept_t = uint; 139 } 140 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/powerpc/bits/fenv.h 141 else version (PPC_Any) 142 { 143 alias fenv_t = double; 144 alias fexcept_t = uint; 145 } 146 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/riscv/bits/fenv.h 147 else version (RISCV_Any) 148 { 149 alias fenv_t = uint; 150 alias fexcept_t = uint; 151 } 152 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/sparc/fpu/bits/fenv.h 153 else version (SPARC_Any) 154 { 155 import core.stdc.config : c_ulong; 156 157 alias fenv_t = c_ulong; 158 alias fexcept_t = c_ulong; 159 } 160 // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/s390/fpu/bits/fenv.h 161 else version (IBMZ_Any) 162 { 163 struct fenv_t 164 { 165 fexcept_t __fpc; 166 void* __unused; 167 } 168 169 alias fexcept_t = uint; 170 } 171 else version (LoongArch64) 172 { 173 struct fenv_t 174 { 175 uint __fp_control_register; 176 } 177 178 alias fexcept_t = uint; 179 } 180 else 181 { 182 static assert(0, "Unimplemented architecture"); 183 } 184 } 185 else version (CRuntime_DigitalMars) 186 { 187 struct fenv_t 188 { 189 ushort status; 190 ushort control; 191 ushort round; 192 ushort[2] reserved; 193 } 194 alias fexcept_t = int; 195 } 196 else version (CRuntime_Microsoft) 197 { 198 struct fenv_t 199 { 200 uint ctl; 201 uint stat; 202 } 203 204 alias fexcept_t = uint; 205 } 206 else version (Darwin) 207 { 208 version (BigEndian) 209 { 210 alias uint fenv_t; 211 alias uint fexcept_t; 212 } 213 version (LittleEndian) 214 { 215 struct fenv_t 216 { 217 ushort __control; 218 ushort __status; 219 uint __mxcsr; 220 byte[8] __reserved; 221 } 222 223 alias ushort fexcept_t; 224 } 225 } 226 else version (FreeBSD) 227 { 228 struct fenv_t 229 { 230 ushort __control; 231 ushort __mxcsr_hi; 232 ushort __status; 233 ushort __mxcsr_lo; 234 uint __tag; 235 byte[16] __other; 236 } 237 238 alias ushort fexcept_t; 239 } 240 else version (NetBSD) 241 { 242 version (X86_64) 243 { 244 struct fenv_t 245 { 246 struct _x87 247 { 248 uint control; /* Control word register */ 249 uint status; /* Status word register */ 250 uint tag; /* Tag word register */ 251 uint[4] others; /* EIP, Pointer Selector, etc */ 252 } 253 _x87 x87; 254 255 uint mxcsr; /* Control and status register */ 256 } 257 } 258 version (X86) 259 { 260 struct fenv_t 261 { 262 struct _x87 263 { 264 ushort control; /* Control word register */ 265 ushort unused1; 266 ushort status; /* Status word register */ 267 ushort unused2; 268 ushort tag; /* Tag word register */ 269 ushort unused3; 270 uint[4] others; /* EIP, Pointer Selector, etc */ 271 } 272 _x87 x87; 273 uint mxcsr; /* Control and status register */ 274 } 275 276 } 277 278 alias uint fexcept_t; 279 } 280 else version (OpenBSD) 281 { 282 struct fenv_t 283 { 284 struct __x87 285 { 286 uint __control; 287 uint __status; 288 uint __tag; 289 uint[4] __others; 290 } 291 } 292 uint __mxcsr; 293 294 alias fexcept_t = uint; 295 } 296 else version (DragonFlyBSD) 297 { 298 struct fenv_t 299 { 300 struct _x87 301 { 302 uint control; 303 uint status; 304 uint tag; 305 uint[4] others; 306 } 307 _x87 x87; 308 309 uint mxcsr; 310 } 311 312 alias uint fexcept_t; 313 } 314 else version (CRuntime_Bionic) 315 { 316 version (X86) 317 { 318 struct fenv_t 319 { 320 ushort __control; 321 ushort __mxcsr_hi; 322 ushort __status; 323 ushort __mxcsr_lo; 324 uint __tag; 325 byte[16] __other; 326 } 327 328 alias ushort fexcept_t; 329 } 330 else version (ARM) 331 { 332 alias uint fenv_t; 333 alias uint fexcept_t; 334 } 335 else version (AArch64) 336 { 337 struct fenv_t 338 { 339 uint __control; 340 uint __status; 341 } 342 343 alias uint fexcept_t; 344 } 345 else version (X86_64) 346 { 347 struct fenv_t 348 { 349 struct _x87 350 { 351 uint __control; 352 uint __status; 353 uint __tag; 354 uint[4] __others; 355 } 356 _x87 __x87; 357 358 uint __mxcsr; 359 } 360 361 alias uint fexcept_t; 362 } 363 else 364 { 365 static assert(false, "Architecture not supported."); 366 } 367 } 368 else version (Solaris) 369 { 370 import core.stdc.config : c_ulong; 371 372 enum FEX_NUM_EXC = 12; 373 374 struct fex_handler_t 375 { 376 int __mode; 377 void function() __handler; 378 } 379 380 struct fenv_t 381 { 382 fex_handler_t[FEX_NUM_EXC] __handler; 383 c_ulong __fsr; 384 } 385 386 alias int fexcept_t; 387 } 388 else version (CRuntime_Musl) 389 { 390 version (AArch64) 391 { 392 struct fenv_t 393 { 394 uint __fpcr; 395 uint __fpsr; 396 } 397 alias uint fexcept_t; 398 } 399 else version (ARM) 400 { 401 import core.stdc.config : c_ulong; 402 403 struct fenv_t 404 { 405 c_ulong __cw; 406 } 407 alias c_ulong fexcept_t; 408 } 409 else version (IBMZ_Any) 410 { 411 alias uint fenv_t; 412 alias uint fexcept_t; 413 } 414 else version (MIPS_Any) 415 { 416 struct fenv_t 417 { 418 uint __cw; 419 } 420 alias ushort fexcept_t; 421 } 422 else version (PPC_Any) 423 { 424 alias double fenv_t; 425 alias uint fexcept_t; 426 } 427 else version (X86_Any) 428 { 429 struct fenv_t 430 { 431 ushort __control_word; 432 ushort __unused1; 433 ushort __status_word; 434 ushort __unused2; 435 ushort __tags; 436 ushort __unused3; 437 uint __eip; 438 ushort __cs_selector; 439 ushort __opcode; 440 uint __data_offset; 441 ushort __data_selector; 442 ushort __unused5; 443 version (X86_64) 444 uint __mxcsr; 445 } 446 alias ushort fexcept_t; 447 } 448 else 449 { 450 static assert(false, "Architecture not supported."); 451 } 452 } 453 else version (CRuntime_UClibc) 454 { 455 version (X86) 456 { 457 struct fenv_t 458 { 459 ushort __control_word; 460 ushort __unused1; 461 ushort __status_word; 462 ushort __unused2; 463 ushort __tags; 464 ushort __unused3; 465 uint __eip; 466 ushort __cs_selector; 467 ushort __opcode; 468 uint __data_offset; 469 ushort __data_selector; 470 ushort __unused5; 471 } 472 473 alias fexcept_t = ushort; 474 } 475 else version (X86_64) 476 { 477 struct fenv_t 478 { 479 ushort __control_word; 480 ushort __unused1; 481 ushort __status_word; 482 ushort __unused2; 483 ushort __tags; 484 ushort __unused3; 485 uint __eip; 486 ushort __cs_selector; 487 ushort __opcode; 488 uint __data_offset; 489 ushort __data_selector; 490 ushort __unused5; 491 uint __mxcsr; 492 } 493 494 alias fexcept_t = ushort; 495 } 496 else version (MIPS_Any) 497 { 498 struct fenv_t 499 { 500 uint __fp_control_register; 501 } 502 503 alias fexcept_t = ushort; 504 } 505 else version (ARM) 506 { 507 struct fenv_t 508 { 509 uint __cw; 510 } 511 512 alias fexcept_t = uint; 513 } 514 else 515 { 516 static assert(false, "Architecture not supported."); 517 } 518 } 519 else 520 { 521 static assert( false, "Unsupported platform" ); 522 } 523 524 version (CRuntime_Microsoft) 525 { 526 enum 527 { 528 FE_INEXACT = 1, /// 529 FE_UNDERFLOW = 2, /// 530 FE_OVERFLOW = 4, /// 531 FE_DIVBYZERO = 8, /// 532 FE_INVALID = 0x10, /// 533 FE_ALL_EXCEPT = 0x1F, /// 534 FE_TONEAREST = 0, /// 535 FE_UPWARD = 0x100, /// 536 FE_DOWNWARD = 0x200, /// 537 FE_TOWARDZERO = 0x300, /// 538 } 539 } 540 else version (Solaris) 541 { 542 version (SPARC_Any) 543 { 544 enum 545 { 546 FE_TONEAREST = 0, 547 FE_TOWARDZERO = 1, 548 FE_UPWARD = 2, 549 FE_DOWNWARD = 3, 550 } 551 552 enum 553 { 554 FE_INEXACT = 0x01, 555 FE_DIVBYZERO = 0x02, 556 FE_UNDERFLOW = 0x04, 557 FE_OVERFLOW = 0x08, 558 FE_INVALID = 0x10, 559 FE_ALL_EXCEPT = 0x1f, 560 } 561 562 } 563 else version (X86_Any) 564 { 565 enum 566 { 567 FE_TONEAREST = 0, 568 FE_DOWNWARD = 1, 569 FE_UPWARD = 2, 570 FE_TOWARDZERO = 3, 571 } 572 573 enum 574 { 575 FE_INVALID = 0x01, 576 FE_DIVBYZERO = 0x04, 577 FE_OVERFLOW = 0x08, 578 FE_UNDERFLOW = 0x10, 579 FE_INEXACT = 0x20, 580 FE_ALL_EXCEPT = 0x3d, 581 } 582 } 583 else 584 { 585 static assert(0, "Unimplemented architecture"); 586 } 587 } 588 else 589 { 590 version (X86) 591 { 592 // Define bits representing the exception. 593 enum 594 { 595 FE_INVALID = 0x01, /// 596 FE_DENORMAL = 0x02, /// non-standard 597 FE_DIVBYZERO = 0x04, /// 598 FE_OVERFLOW = 0x08, /// 599 FE_UNDERFLOW = 0x10, /// 600 FE_INEXACT = 0x20, /// 601 FE_ALL_EXCEPT = 0x3F, /// 602 } 603 604 // The ix87 FPU supports all of the four defined rounding modes. 605 enum 606 { 607 FE_TONEAREST = 0, /// 608 FE_DOWNWARD = 0x400, /// 609 FE_UPWARD = 0x800, /// 610 FE_TOWARDZERO = 0xC00, /// 611 } 612 } 613 else version (X86_64) 614 { 615 // Define bits representing the exception. 616 enum 617 { 618 FE_INVALID = 0x01, /// 619 FE_DENORMAL = 0x02, /// non-standard 620 FE_DIVBYZERO = 0x04, /// 621 FE_OVERFLOW = 0x08, /// 622 FE_UNDERFLOW = 0x10, /// 623 FE_INEXACT = 0x20, /// 624 FE_ALL_EXCEPT = 0x3F, /// 625 } 626 627 // The ix87 FPU supports all of the four defined rounding modes. 628 enum 629 { 630 FE_TONEAREST = 0, /// 631 FE_DOWNWARD = 0x400, /// 632 FE_UPWARD = 0x800, /// 633 FE_TOWARDZERO = 0xC00, /// 634 } 635 } 636 else version (ARM_Any) 637 { 638 // Define bits representing exceptions in the FPU status word. 639 enum 640 { 641 FE_INVALID = 1, /// 642 FE_DIVBYZERO = 2, /// 643 FE_OVERFLOW = 4, /// 644 FE_UNDERFLOW = 8, /// 645 FE_INEXACT = 16, /// 646 FE_ALL_EXCEPT = 31, /// 647 } 648 649 // VFP supports all of the four defined rounding modes. 650 enum 651 { 652 FE_TONEAREST = 0, /// 653 FE_UPWARD = 0x400000, /// 654 FE_DOWNWARD = 0x800000, /// 655 FE_TOWARDZERO = 0xC00000, /// 656 } 657 } 658 else version (HPPA_Any) 659 { 660 // Define bits representing the exception. 661 enum 662 { 663 FE_INEXACT = 0x01, /// 664 FE_UNDERFLOW = 0x02, /// 665 FE_OVERFLOW = 0x04, /// 666 FE_DIVBYZERO = 0x08, /// 667 FE_INVALID = 0x10, /// 668 FE_ALL_EXCEPT = 0x1F, /// 669 } 670 671 // The HPPA FPU supports all of the four defined rounding modes. 672 enum 673 { 674 FE_TONEAREST = 0x0, /// 675 FE_TOWARDZERO = 0x200, /// 676 FE_UPWARD = 0x400, /// 677 FE_DOWNWARD = 0x600, /// 678 } 679 } 680 else version (MIPS_Any) 681 { 682 // Define bits representing the exception. 683 enum 684 { 685 FE_INEXACT = 0x04, /// 686 FE_UNDERFLOW = 0x08, /// 687 FE_OVERFLOW = 0x10, /// 688 FE_DIVBYZERO = 0x20, /// 689 FE_INVALID = 0x40, /// 690 FE_ALL_EXCEPT = 0x7C, /// 691 } 692 693 // The MIPS FPU supports all of the four defined rounding modes. 694 enum 695 { 696 FE_TONEAREST = 0x0, /// 697 FE_TOWARDZERO = 0x1, /// 698 FE_UPWARD = 0x2, /// 699 FE_DOWNWARD = 0x3, /// 700 } 701 } 702 else version (PPC_Any) 703 { 704 // Define bits representing the exception. 705 enum 706 { 707 FE_INEXACT = 0x2000000, /// 708 FE_DIVBYZERO = 0x4000000, /// 709 FE_UNDERFLOW = 0x8000000, /// 710 FE_OVERFLOW = 0x10000000, /// 711 FE_INVALID = 0x20000000, /// 712 FE_INVALID_SNAN = 0x1000000, /// non-standard 713 FE_INVALID_ISI = 0x800000, /// non-standard 714 FE_INVALID_IDI = 0x400000, /// non-standard 715 FE_INVALID_ZDZ = 0x200000, /// non-standard 716 FE_INVALID_IMZ = 0x100000, /// non-standard 717 FE_INVALID_COMPARE = 0x80000, /// non-standard 718 FE_INVALID_SOFTWARE = 0x400, /// non-standard 719 FE_INVALID_SQRT = 0x200, /// non-standard 720 FE_INVALID_INTEGER_CONVERSION = 0x100, /// non-standard 721 FE_ALL_INVALID = 0x1F80700, /// non-standard 722 FE_ALL_EXCEPT = 0x3E000000, /// 723 } 724 725 // PowerPC chips support all of the four defined rounding modes. 726 enum 727 { 728 FE_TONEAREST = 0, /// 729 FE_TOWARDZERO = 1, /// 730 FE_UPWARD = 2, /// 731 FE_DOWNWARD = 3, /// 732 } 733 } 734 else version (RISCV_Any) 735 { 736 // Define bits representing exceptions in the FPSR status word. 737 enum 738 { 739 FE_INEXACT = 0x01, /// 740 FE_UNDERFLOW = 0x02, /// 741 FE_OVERFLOW = 0x04, /// 742 FE_DIVBYZERO = 0x08, /// 743 FE_INVALID = 0x10, /// 744 FE_ALL_EXCEPT = 0x1f, /// 745 } 746 747 // Define bits representing rounding modes in the FPCR Rmode field. 748 enum 749 { 750 FE_TONEAREST = 0x0, /// 751 FE_TOWARDZERO = 0x1, /// 752 FE_DOWNWARD = 0x2, /// 753 FE_UPWARD = 0x3, /// 754 } 755 } 756 else version (SPARC_Any) 757 { 758 // Define bits representing the exception. 759 enum 760 { 761 FE_INVALID = 0x200, /// 762 FE_OVERFLOW = 0x100, /// 763 FE_UNDERFLOW = 0x80, /// 764 FE_DIVBYZERO = 0x40, /// 765 FE_INEXACT = 0x20, /// 766 FE_ALL_EXCEPT = 0x3E0, /// 767 } 768 769 // The Sparc FPU supports all of the four defined rounding modes. 770 enum 771 { 772 FE_TONEAREST = 0x0, /// 773 FE_TOWARDZERO = 0x40000000, /// 774 FE_UPWARD = 0x80000000, /// 775 FE_DOWNWARD = 0xc0000000, /// 776 } 777 } 778 else version (IBMZ_Any) 779 { 780 // Define bits representing the exception. 781 enum 782 { 783 FE_INVALID = 0x80, /// 784 FE_DIVBYZERO = 0x40, /// 785 FE_OVERFLOW = 0x20, /// 786 FE_UNDERFLOW = 0x10, /// 787 FE_INEXACT = 0x08, /// 788 FE_ALL_EXCEPT = 0xF8, /// 789 } 790 791 // SystemZ supports all of the four defined rounding modes. 792 enum 793 { 794 FE_TONEAREST = 0x0, /// 795 FE_DOWNWARD = 0x3, /// 796 FE_UPWARD = 0x2, /// 797 FE_TOWARDZERO = 0x1, /// 798 } 799 } 800 else version (LoongArch64) 801 { 802 // Define bits representing exceptions in the FPSR status word. 803 enum 804 { 805 FE_INEXACT = 0x010000, /// 806 FE_UNDERFLOW = 0x020000, /// 807 FE_OVERFLOW = 0x040000, /// 808 FE_DIVBYZERO = 0x080000, /// 809 FE_INVALID = 0x100000, /// 810 FE_ALL_EXCEPT = 0x1f0000, /// 811 } 812 813 // Define bits representing rounding modes in the FPCR Rmode field. 814 enum 815 { 816 FE_TONEAREST = 0x000, /// 817 FE_TOWARDZERO = 0x100, /// 818 FE_DOWNWARD = 0x200, /// 819 FE_UPWARD = 0x300, /// 820 } 821 } 822 else 823 { 824 static assert(0, "Unimplemented architecture"); 825 } 826 827 } 828 829 version (GNUFP) 830 { 831 /// 832 enum FE_DFL_ENV = cast(fenv_t*)(-1); 833 } 834 else version (CRuntime_DigitalMars) 835 { 836 private extern __gshared fenv_t _FE_DFL_ENV; 837 /// 838 enum fenv_t* FE_DFL_ENV = &_FE_DFL_ENV; 839 } 840 else version (CRuntime_Microsoft) 841 { 842 private extern __gshared fenv_t _Fenv0; 843 /// 844 enum FE_DFL_ENV = &_Fenv0; 845 } 846 else version (Darwin) 847 { 848 private extern __gshared fenv_t _FE_DFL_ENV; 849 /// 850 enum FE_DFL_ENV = &_FE_DFL_ENV; 851 } 852 else version (FreeBSD) 853 { 854 private extern const fenv_t __fe_dfl_env; 855 /// 856 enum FE_DFL_ENV = &__fe_dfl_env; 857 } 858 else version (NetBSD) 859 { 860 private extern const fenv_t __fe_dfl_env; 861 /// 862 enum FE_DFL_ENV = &__fe_dfl_env; 863 } 864 else version (OpenBSD) 865 { 866 private extern const fenv_t __fe_dfl_env; 867 /// 868 enum FE_DFL_ENV = &__fe_dfl_env; 869 } 870 else version (DragonFlyBSD) 871 { 872 private extern const fenv_t __fe_dfl_env; 873 /// 874 enum FE_DFL_ENV = &__fe_dfl_env; 875 } 876 else version (CRuntime_Bionic) 877 { 878 private extern const fenv_t __fe_dfl_env; 879 /// 880 enum FE_DFL_ENV = &__fe_dfl_env; 881 } 882 else version (Solaris) 883 { 884 private extern const fenv_t __fenv_def_env; 885 /// 886 enum FE_DFL_ENV = &__fenv_def_env; 887 } 888 else version (CRuntime_Musl) 889 { 890 /// 891 enum FE_DFL_ENV = cast(fenv_t*)(-1); 892 } 893 else version (CRuntime_UClibc) 894 { 895 /// 896 enum FE_DFL_ENV = cast(fenv_t*)(-1); 897 } 898 else 899 { 900 static assert( false, "Unsupported platform" ); 901 } 902 903 /// 904 int feclearexcept(int excepts); 905 906 /// 907 int fetestexcept(int excepts); 908 /// 909 int feholdexcept(fenv_t* envp); 910 911 /// 912 int fegetexceptflag(fexcept_t* flagp, int excepts); 913 /// 914 int fesetexceptflag(const scope fexcept_t* flagp, int excepts); 915 916 /// 917 int fegetround(); 918 /// 919 int fesetround(int round); 920 921 /// 922 int fegetenv(fenv_t* envp); 923 /// 924 int fesetenv(const scope fenv_t* envp); 925 926 // MS define feraiseexcept() and feupdateenv() inline. 927 version (CRuntime_Microsoft) // supported since MSVCRT 12 (VS 2013) only 928 { 929 /// 930 int feraiseexcept()(int excepts) 931 { 932 struct Entry 933 { 934 int exceptVal; 935 double num; 936 double denom; 937 } 938 static __gshared immutable(Entry[5]) table = 939 [ // Raise exception by evaluating num / denom: 940 { FE_INVALID, 0.0, 0.0 }, 941 { FE_DIVBYZERO, 1.0, 0.0 }, 942 { FE_OVERFLOW, 1e+300, 1e-300 }, 943 { FE_UNDERFLOW, 1e-300, 1e+300 }, 944 { FE_INEXACT, 2.0, 3.0 } 945 ]; 946 947 if ((excepts &= FE_ALL_EXCEPT) == 0) 948 return 0; 949 950 // Raise the exceptions not masked: 951 double ans = void; 952 foreach (i; 0 .. table.length) 953 { 954 if ((excepts & table[i].exceptVal) != 0) 955 ans = table[i].num / table[i].denom; 956 } 957 958 return 0; 959 } 960 961 /// 962 int feupdateenv()(const scope fenv_t* envp) 963 { 964 int excepts = fetestexcept(FE_ALL_EXCEPT); 965 return (fesetenv(envp) != 0 || feraiseexcept(excepts) != 0 ? 1 : 0); 966 } 967 } 968 else 969 { 970 /// 971 int feraiseexcept(int excepts); 972 /// 973 int feupdateenv(const scope fenv_t* envp); 974 }