2 * Floating point functions that are difficult or impossible to implement
5 * Copyright (C) 2009-2010 Nick Bowler.
7 * License BSD2: 2-clause BSD license. See LICENSE for full terms.
8 * This is free software: you are free to change and redistribute it.
9 * There is NO WARRANTY, to the extent permitted by law.
19 #pragma STDC FENV_ACCESS ON
21 int double_format(char *buf
, char spec
, int precision
, double val
)
27 return snprintf(NULL
, 0, fmt
, precision
, val
);
28 return sprintf(buf
, fmt
, precision
, val
);
31 double double_signum(double val
)
38 float float_signum(float val
)
45 int double_classify(double val
)
47 switch (fpclassify(val
)) {
63 int float_classify(float val
)
65 switch (fpclassify(val
)) {
81 int double_compare(double a
, double b
)
89 if (isunordered(a
, b
))
94 int float_compare(float a
, float b
)
102 if (isunordered(a
, b
))
107 int set_roundmode(int mode
)
113 cmode
= FE_TONEAREST
;
122 cmode
= FE_TOWARDZERO
;
128 return fesetround(cmode
);
131 int get_roundmode(void)
133 int cmode
= fegetround();
149 int fenv_restore(fenv_t
*env
, unsigned *excepts
)
151 int raw_excepts
= fetestexcept(FE_ALL_EXCEPT
);
157 if (raw_excepts
& FE_DIVBYZERO
) *excepts
|= 0x01;
160 if (raw_excepts
& FE_INEXACT
) *excepts
|= 0x02;
163 if (raw_excepts
& FE_INVALID
) *excepts
|= 0x04;
166 if (raw_excepts
& FE_OVERFLOW
) *excepts
|= 0x08;
169 if (raw_excepts
& FE_UNDERFLOW
) *excepts
|= 0x10;
173 return fesetenv(env
);
176 int fenv_raise_excepts(unsigned excepts
)
181 if (excepts
& 0x01) raw_excepts
|= FE_DIVBYZERO
;
184 if (excepts
& 0x02) raw_excepts
|= FE_INEXACT
;
187 if (excepts
& 0x04) raw_excepts
|= FE_INVALID
;
190 if (excepts
& 0x08) raw_excepts
|= FE_OVERFLOW
;
193 if (excepts
& 0x10) raw_excepts
|= FE_UNDERFLOW
;
195 return feraiseexcept(raw_excepts
);