1# 2# 3# Nim's Runtime Library 4# (c) Copyright 2015 Andreas Rumpf 5# 6# See the file "copying.txt", included in this 7# distribution, for details about the copyright. 8# 9 10## Floating-point environment. Handling of floating-point rounding and 11## exceptions (overflow, division by zero, etc.). 12## The types, vars and procs are bindings for the C standard library 13## [<fenv.h>](https://en.cppreference.com/w/c/numeric/fenv) header. 14 15when defined(posix) and not defined(genode): 16 {.passl: "-lm".} 17 18var 19 FE_DIVBYZERO* {.importc, header: "<fenv.h>".}: cint 20 ## division by zero 21 FE_INEXACT* {.importc, header: "<fenv.h>".}: cint 22 ## inexact result 23 FE_INVALID* {.importc, header: "<fenv.h>".}: cint 24 ## invalid operation 25 FE_OVERFLOW* {.importc, header: "<fenv.h>".}: cint 26 ## result not representable due to overflow 27 FE_UNDERFLOW* {.importc, header: "<fenv.h>".}: cint 28 ## result not representable due to underflow 29 FE_ALL_EXCEPT* {.importc, header: "<fenv.h>".}: cint 30 ## bitwise OR of all supported exceptions 31 FE_DOWNWARD* {.importc, header: "<fenv.h>".}: cint 32 ## round toward -Inf 33 FE_TONEAREST* {.importc, header: "<fenv.h>".}: cint 34 ## round to nearest 35 FE_TOWARDZERO* {.importc, header: "<fenv.h>".}: cint 36 ## round toward 0 37 FE_UPWARD* {.importc, header: "<fenv.h>".}: cint 38 ## round toward +Inf 39 FE_DFL_ENV* {.importc, header: "<fenv.h>".}: cint 40 ## macro of type pointer to `fenv_t` to be used as the argument 41 ## to functions taking an argument of type `fenv_t`; in this 42 ## case the default environment will be used 43 44type 45 Tfenv* {.importc: "fenv_t", header: "<fenv.h>", final, pure.} = 46 object ## Represents the entire floating-point environment. The 47 ## floating-point environment refers collectively to any 48 ## floating-point status flags and control modes supported 49 ## by the implementation. 50 Tfexcept* {.importc: "fexcept_t", header: "<fenv.h>", final, pure.} = 51 object ## Represents the floating-point status flags collectively, 52 ## including any status the implementation associates with the 53 ## flags. A floating-point status flag is a system variable 54 ## whose value is set (but never cleared) when a floating-point 55 ## exception is raised, which occurs as a side effect of 56 ## exceptional floating-point arithmetic to provide auxiliary 57 ## information. A floating-point control mode is a system variable 58 ## whose value may be set by the user to affect the subsequent 59 ## behavior of floating-point arithmetic. 60 61proc feclearexcept*(excepts: cint): cint {.importc, header: "<fenv.h>".} 62 ## Clear the supported exceptions represented by `excepts`. 63 64proc fegetexceptflag*(flagp: ptr Tfexcept, excepts: cint): cint {. 65 importc, header: "<fenv.h>".} 66 ## Store implementation-defined representation of the exception flags 67 ## indicated by `excepts` in the object pointed to by `flagp`. 68 69proc feraiseexcept*(excepts: cint): cint {.importc, header: "<fenv.h>".} 70 ## Raise the supported exceptions represented by `excepts`. 71 72proc fesetexceptflag*(flagp: ptr Tfexcept, excepts: cint): cint {. 73 importc, header: "<fenv.h>".} 74 ## Set complete status for exceptions indicated by `excepts` according to 75 ## the representation in the object pointed to by `flagp`. 76 77proc fetestexcept*(excepts: cint): cint {.importc, header: "<fenv.h>".} 78 ## Determine which of subset of the exceptions specified by `excepts` are 79 ## currently set. 80 81proc fegetround*(): cint {.importc, header: "<fenv.h>".} 82 ## Get current rounding direction. 83 84proc fesetround*(roundingDirection: cint): cint {.importc, header: "<fenv.h>".} 85 ## Establish the rounding direction represented by `roundingDirection`. 86 87proc fegetenv*(envp: ptr Tfenv): cint {.importc, header: "<fenv.h>".} 88 ## Store the current floating-point environment in the object pointed 89 ## to by `envp`. 90 91proc feholdexcept*(envp: ptr Tfenv): cint {.importc, header: "<fenv.h>".} 92 ## Save the current environment in the object pointed to by `envp`, clear 93 ## exception flags and install a non-stop mode (if available) for all 94 ## exceptions. 95 96proc fesetenv*(a1: ptr Tfenv): cint {.importc, header: "<fenv.h>".} 97 ## Establish the floating-point environment represented by the object 98 ## pointed to by `envp`. 99 100proc feupdateenv*(envp: ptr Tfenv): cint {.importc, header: "<fenv.h>".} 101 ## Save current exceptions in temporary storage, install environment 102 ## represented by object pointed to by `envp` and raise exceptions 103 ## according to saved exceptions. 104 105const 106 FLT_RADIX = 2 ## the radix of the exponent representation 107 108 FLT_MANT_DIG = 24 ## the number of base FLT_RADIX digits in the mantissa part of a float 109 FLT_DIG = 6 ## the number of digits of precision of a float 110 FLT_MIN_EXP = -125 ## the minimum value of base FLT_RADIX in the exponent part of a float 111 FLT_MAX_EXP = 128 ## the maximum value of base FLT_RADIX in the exponent part of a float 112 FLT_MIN_10_EXP = -37 ## the minimum value in base 10 of the exponent part of a float 113 FLT_MAX_10_EXP = 38 ## the maximum value in base 10 of the exponent part of a float 114 FLT_MIN = 1.17549435e-38'f32 ## the minimum value of a float 115 FLT_MAX = 3.40282347e+38'f32 ## the maximum value of a float 116 FLT_EPSILON = 1.19209290e-07'f32 ## the difference between 1 and the least value greater than 1 of a float 117 118 DBL_MANT_DIG = 53 ## the number of base FLT_RADIX digits in the mantissa part of a double 119 DBL_DIG = 15 ## the number of digits of precision of a double 120 DBL_MIN_EXP = -1021 ## the minimum value of base FLT_RADIX in the exponent part of a double 121 DBL_MAX_EXP = 1024 ## the maximum value of base FLT_RADIX in the exponent part of a double 122 DBL_MIN_10_EXP = -307 ## the minimum value in base 10 of the exponent part of a double 123 DBL_MAX_10_EXP = 308 ## the maximum value in base 10 of the exponent part of a double 124 DBL_MIN = 2.2250738585072014E-308 ## the minimal value of a double 125 DBL_MAX = 1.7976931348623157E+308 ## the minimal value of a double 126 DBL_EPSILON = 2.2204460492503131E-16 ## the difference between 1 and the least value greater than 1 of a double 127 128template fpRadix*: int = FLT_RADIX 129 ## The (integer) value of the radix used to represent any floating 130 ## point type on the architecture used to build the program. 131 132template mantissaDigits*(T: typedesc[float32]): int = FLT_MANT_DIG 133 ## Number of digits (in base `floatingPointRadix`) in the mantissa 134 ## of 32-bit floating-point numbers. 135template digits*(T: typedesc[float32]): int = FLT_DIG 136 ## Number of decimal digits that can be represented in a 137 ## 32-bit floating-point type without losing precision. 138template minExponent*(T: typedesc[float32]): int = FLT_MIN_EXP 139 ## Minimum (negative) exponent for 32-bit floating-point numbers. 140template maxExponent*(T: typedesc[float32]): int = FLT_MAX_EXP 141 ## Maximum (positive) exponent for 32-bit floating-point numbers. 142template min10Exponent*(T: typedesc[float32]): int = FLT_MIN_10_EXP 143 ## Minimum (negative) exponent in base 10 for 32-bit floating-point 144 ## numbers. 145template max10Exponent*(T: typedesc[float32]): int = FLT_MAX_10_EXP 146 ## Maximum (positive) exponent in base 10 for 32-bit floating-point 147 ## numbers. 148template minimumPositiveValue*(T: typedesc[float32]): float32 = FLT_MIN 149 ## The smallest positive (nonzero) number that can be represented in a 150 ## 32-bit floating-point type. 151template maximumPositiveValue*(T: typedesc[float32]): float32 = FLT_MAX 152 ## The largest positive number that can be represented in a 32-bit 153 ## floating-point type. 154template epsilon*(T: typedesc[float32]): float32 = FLT_EPSILON 155 ## The difference between 1.0 and the smallest number greater than 156 ## 1.0 that can be represented in a 32-bit floating-point type. 157 158template mantissaDigits*(T: typedesc[float64]): int = DBL_MANT_DIG 159 ## Number of digits (in base `floatingPointRadix`) in the mantissa 160 ## of 64-bit floating-point numbers. 161template digits*(T: typedesc[float64]): int = DBL_DIG 162 ## Number of decimal digits that can be represented in a 163 ## 64-bit floating-point type without losing precision. 164template minExponent*(T: typedesc[float64]): int = DBL_MIN_EXP 165 ## Minimum (negative) exponent for 64-bit floating-point numbers. 166template maxExponent*(T: typedesc[float64]): int = DBL_MAX_EXP 167 ## Maximum (positive) exponent for 64-bit floating-point numbers. 168template min10Exponent*(T: typedesc[float64]): int = DBL_MIN_10_EXP 169 ## Minimum (negative) exponent in base 10 for 64-bit floating-point 170 ## numbers. 171template max10Exponent*(T: typedesc[float64]): int = DBL_MAX_10_EXP 172 ## Maximum (positive) exponent in base 10 for 64-bit floating-point 173 ## numbers. 174template minimumPositiveValue*(T: typedesc[float64]): float64 = DBL_MIN 175 ## The smallest positive (nonzero) number that can be represented in a 176 ## 64-bit floating-point type. 177template maximumPositiveValue*(T: typedesc[float64]): float64 = DBL_MAX 178 ## The largest positive number that can be represented in a 64-bit 179 ## floating-point type. 180template epsilon*(T: typedesc[float64]): float64 = DBL_EPSILON 181 ## The difference between 1.0 and the smallest number greater than 182 ## 1.0 that can be represented in a 64-bit floating-point type. 183