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