Skip to content

Commit 9d6c51f

Browse files
committed
Attempted to correct the quiet comparison functions (Works at -O0, but not at -O1 or higher). Added a few C23 functions
1 parent df15dc3 commit 9d6c51f

File tree

6 files changed

+267
-207
lines changed

6 files changed

+267
-207
lines changed

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
MIT License
22

3-
Copyright (c) 2024 ZERICO2005
3+
Copyright (c) 2024 - 2025 ZERICO2005
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
`quadmath_cpp` provides C++ overloads for `__float128` and `<quadmath.h>` functions. This allows you to use `<quadmath.h>` in templated functions. Instead of calling `sinq(x)` or `powq(x, y)`, you can now call `sin(x)` or `pow(x, y)` just like you would with `float` or `double`.
2+
3+
`quadmath_cpp` also includes functions not present in `<quadmath.h>`, such as `islessgreater(x, y)` and `fpclassify(x)` from C++11, in addition to a few C23 functions like `iseqsig(x, y)`.
4+
5+
Include the `quadmath_cpp.h` header in your code to use it. The header should compile fine on GCC from C++98 to C++23

README.txt

Lines changed: 0 additions & 5 deletions
This file was deleted.

quadmath_cpp.h

Lines changed: 184 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1,169 +1,184 @@
1-
/*
2-
** Author: zerico2005 (2024)
3-
** Project: quadmath_cpp
4-
** License: MIT License
5-
** A copy of the MIT License should be included with
6-
** this project. If not, see https://opensource.org/license/MIT
7-
*/
8-
9-
#ifndef QUADMATH_CPP_H
10-
#define QUADMATH_CPP_H
11-
12-
//------------------------------------------------------------------------------
13-
// <quadmath.h> overloads
14-
//------------------------------------------------------------------------------
15-
16-
#include <cmath>
17-
#include <quadmath.h>
18-
19-
/* Classification */
20-
21-
inline bool signbit(__float128 x) { return (signbitq(x) != 0); }
22-
inline bool isfinite(__float128 x) { return (finiteq(x) != 0); }
23-
inline bool isinf(__float128 x) { return (isinfq(x) != 0); }
24-
inline bool isnan(__float128 x) { return (isnanq(x) != 0); }
25-
inline bool issignaling(__float128 x) { return (issignalingq(x) != 0); }
26-
27-
/* Manipulation */
28-
29-
inline __float128 fabs(__float128 x) { return fabsq(x); }
30-
inline __float128 copysign(__float128 x, __float128 y) { return copysignq(x, y); }
31-
inline __float128 nextafter(__float128 x, __float128 y) { return nextafterq(x, y); }
32-
33-
/* Float Exponents */
34-
35-
inline int ilogb(__float128 x) { return ilogbq(x); }
36-
inline __float128 frexp (__float128 x, int* exp) { return frexpq (x, exp); }
37-
inline __float128 ldexp (__float128 x, int exp) { return ldexpq (x, exp); }
38-
inline __float128 scalbn (__float128 x, int exp) { return scalbnq (x, exp); }
39-
inline __float128 scalbln(__float128 x, long exp) { return scalblnq(x, exp); }
40-
41-
/* Arithmetic */
42-
43-
inline __float128 fmax(__float128 x, __float128 y) { return fmaxq(x, y); }
44-
inline __float128 fmin(__float128 x, __float128 y) { return fminq(x, y); }
45-
inline __float128 fdim(__float128 x, __float128 y) { return fdimq(x, y); }
46-
inline __float128 fma(__float128 x, __float128 y, __float128 z) { return fmaq(x, y, z); }
47-
inline __float128 sqrt(__float128 x) { return sqrtq(x); }
48-
inline __float128 cbrt(__float128 x) { return cbrtq(x); }
49-
inline __float128 hypot(__float128 x, __float128 y) { return hypotq(x, y); }
50-
51-
/* Remainder and Modulus */
52-
53-
inline __float128 fmod(__float128 x, __float128 y) { return fmodq(x, y); }
54-
inline __float128 modf(__float128 x, __float128* int_part) { return modfq(x, int_part); }
55-
inline __float128 remainder(__float128 x, __float128 y) { return remainderq(x, y); }
56-
inline __float128 remquo(__float128 x, __float128 y, int* quo) { return remquoq(x, y, quo); }
57-
58-
/* Rounding */
59-
60-
inline __float128 trunc(__float128 x) { return truncq(x); }
61-
inline __float128 floor(__float128 x) { return floorq(x); }
62-
inline __float128 ceil (__float128 x) { return ceilq (x); }
63-
inline __float128 rint (__float128 x) { return rintq (x); }
64-
inline __float128 round(__float128 x) { return roundq(x); }
65-
inline long lrint (__float128 x) { return lrintq (x); }
66-
inline long lround(__float128 x) { return lroundq(x); }
67-
inline long long llrint (__float128 x) { return llrintq (x); }
68-
inline long long llround(__float128 x) { return llroundq(x); }
69-
inline __float128 nearbyint(__float128 x) { return nearbyintq(x); }
70-
71-
/* Logarithms and Exponents */
72-
73-
inline __float128 log (__float128 x) { return logq (x); }
74-
inline __float128 log1p(__float128 x) { return log1pq(x); }
75-
inline __float128 logb (__float128 x) { return logbq (x); }
76-
inline __float128 log2 (__float128 x) { return log2q (x); }
77-
inline __float128 log10(__float128 x) { return log10q(x); }
78-
inline __float128 exp (__float128 x) { return expq (x); }
79-
inline __float128 expm1(__float128 x) { return expm1q(x); }
80-
inline __float128 exp2 (__float128 x) { return exp2q (x); }
81-
inline __float128 pow(__float128 x, __float128 y) { return powq(x, y); }
82-
83-
/* Trigonometry */
84-
85-
inline __float128 sin (__float128 x) { return sinq (x); }
86-
inline __float128 cos (__float128 x) { return cosq (x); }
87-
inline __float128 tan (__float128 x) { return tanq (x); }
88-
inline __float128 asin (__float128 x) { return asinq (x); }
89-
inline __float128 acos (__float128 x) { return acosq (x); }
90-
inline __float128 atan (__float128 x) { return atanq (x); }
91-
inline __float128 sinh(__float128 x) { return sinhq(x); }
92-
inline __float128 cosh(__float128 x) { return coshq(x); }
93-
inline __float128 tanh(__float128 x) { return tanhq(x); }
94-
inline __float128 asinh(__float128 x) { return asinhq(x); }
95-
inline __float128 acosh(__float128 x) { return acoshq(x); }
96-
inline __float128 atanh(__float128 x) { return atanhq(x); }
97-
inline __float128 atan2(__float128 y, __float128 x) { return atan2q(y, x); }
98-
inline void sincos(__float128 x, __float128* p_sin, __float128* p_cos) { sincosq(x, p_sin, p_cos); }
99-
100-
/* Transcendental Functions */
101-
102-
inline __float128 erf (__float128 x) { return erfq (x); }
103-
inline __float128 erfc(__float128 x) { return erfcq(x); }
104-
inline __float128 lgamma(__float128 x) { return lgammaq(x); }
105-
inline __float128 tgamma(__float128 x) { return tgammaq(x); }
106-
107-
//------------------------------------------------------------------------------
108-
// C++11 <cmath> overloads
109-
//------------------------------------------------------------------------------
110-
111-
/* Manipulation */
112-
113-
inline __float128 nexttoward(__float128 x, long double y) {
114-
return nextafterq(x, static_cast<__float128>(y));
115-
}
116-
117-
/* Compairison */
118-
119-
inline bool isgreater(__float128 x, __float128 y) {
120-
return (x > y);
121-
}
122-
inline bool isgreaterequal(__float128 x, __float128 y) {
123-
return (x >= y);
124-
}
125-
inline bool isless(__float128 x, __float128 y) {
126-
return (x < y);
127-
}
128-
inline bool islessequal(__float128 x, __float128 y) {
129-
return (x <= y);
130-
}
131-
inline bool islessgreater(__float128 x, __float128 y) {
132-
return (x < y) || (x > y);
133-
}
134-
135-
/* Classification */
136-
137-
inline bool isunordered(__float128 x, __float128 y) {
138-
return (isnanq(x) != 0) || (isnanq(y) != 0);
139-
}
140-
141-
inline bool isnormal(__float128 x) {
142-
return (finiteq(x) != 0 && fabsq(x) >= FLT128_MIN);
143-
}
144-
145-
inline int fpclassify(__float128 x) {
146-
return
147-
isinfq(x) ? FP_INFINITE :
148-
isnanq(x) ? FP_NAN :
149-
x == static_cast<__float128>(0.0) ? FP_ZERO :
150-
isnormal(x) ? FP_NORMAL :
151-
FP_SUBNORMAL;
152-
}
153-
154-
//------------------------------------------------------------------------------
155-
// Additional overloads
156-
//------------------------------------------------------------------------------
157-
158-
/** @brief calls `exp(x * M_LN10q)` */
159-
inline __float128 exp10(__float128 x) {
160-
return expq(x * M_LN10q);
161-
}
162-
163-
/** @brief calls `*p_sinh = sinhq(x); *p_cosh = coshq(x);` */
164-
inline void sinhcosh(__float128 x, __float128* p_sinh, __float128* p_cosh) {
165-
*p_sinh = sinhq(x);
166-
*p_cosh = coshq(x);
167-
}
168-
169-
#endif /* QUADMATH_CPP_H */
1+
/*
2+
** Author: zerico2005 (2024 - 2025)
3+
** Project: quadmath_cpp
4+
** License: MIT License
5+
** A copy of the MIT License should be included with
6+
** this project. If not, see https://opensource.org/license/MIT
7+
*/
8+
9+
#ifndef QUADMATH_CPP_H
10+
#define QUADMATH_CPP_H
11+
12+
//------------------------------------------------------------------------------
13+
// <quadmath.h> overloads
14+
//------------------------------------------------------------------------------
15+
16+
#include <quadmath.h>
17+
18+
#if __cplusplus >= 201103L
19+
#include <cmath>
20+
#include <cfenv>
21+
#endif
22+
23+
/* Classification */
24+
25+
inline bool signbit(__float128 x) { return (signbitq(x) != 0); }
26+
inline bool isfinite(__float128 x) { return (finiteq(x) != 0); }
27+
inline bool isinf(__float128 x) { return (isinfq(x) != 0); }
28+
inline bool isnan(__float128 x) { return (isnanq(x) != 0); }
29+
inline bool issignaling(__float128 x) { return (issignalingq(x) != 0); }
30+
31+
inline bool isunordered(__float128 x, __float128 y) {
32+
return ((isnanq(x) != 0) || (isnanq(y) != 0));
33+
}
34+
inline bool isnormal(__float128 x) {
35+
return ((finiteq(x) != 0) && (fabsq(x) >= FLT128_MIN));
36+
}
37+
inline bool issubnormal(__float128 x) {
38+
return ((finiteq(x) != 0) && (fabsq(x) < FLT128_MIN) && (x != static_cast<__float128>(0.0)));
39+
}
40+
41+
#if __cplusplus >= 201103L
42+
43+
inline int fpclassify(__float128 x) {
44+
return
45+
isinfq(x) ? FP_INFINITE :
46+
isnanq(x) ? FP_NAN :
47+
x == static_cast<__float128>(0.0) ? FP_ZERO :
48+
isnormal(x) ? FP_NORMAL :
49+
FP_SUBNORMAL;
50+
}
51+
52+
#endif /* __cplusplus >= 201103L */
53+
54+
/* Quiet Compairison */
55+
56+
inline bool islessgreater(__float128 x, __float128 y) {
57+
return ((x != y) && (isnanq(x) == 0) && (isnanq(y) == 0));
58+
}
59+
60+
#if __cplusplus >= 201103L
61+
62+
inline bool isless(__float128 x, __float128 y) {
63+
bool ignore_fe_expection = !std::fetestexcept(FE_INVALID);
64+
bool result = (x < y);
65+
if (ignore_fe_expection) { std::feclearexcept(FE_INVALID); }
66+
return result;
67+
}
68+
inline bool islessequal(__float128 x, __float128 y) {
69+
bool ignore_fe_expection = !std::fetestexcept(FE_INVALID);
70+
bool result = (x <= y);
71+
if (ignore_fe_expection) { std::feclearexcept(FE_INVALID); }
72+
return result;
73+
}
74+
inline bool isgreater(__float128 x, __float128 y) {
75+
bool ignore_fe_expection = !std::fetestexcept(FE_INVALID);
76+
bool result = (x > y);
77+
if (ignore_fe_expection) { std::feclearexcept(FE_INVALID); }
78+
return result;
79+
}
80+
inline bool isgreaterequal(__float128 x, __float128 y) {
81+
bool ignore_fe_expection = !std::fetestexcept(FE_INVALID);
82+
bool result = (x >= y);
83+
if (ignore_fe_expection) { std::feclearexcept(FE_INVALID); }
84+
return result;
85+
}
86+
87+
#endif /* __cplusplus >= 201103L */
88+
89+
90+
/* signaling comparison */
91+
92+
#if __cplusplus >= 201103L
93+
94+
inline bool iseqsig(__float128 x, __float128 y) {
95+
if ((isnanq(x) != 0) || (isnanq(y) != 0)) {
96+
std::feraiseexcept(FE_INVALID);
97+
}
98+
return (x == y);
99+
}
100+
101+
#endif /* __cplusplus >= 201103L */
102+
103+
/* Manipulation */
104+
105+
inline __float128 fabs(__float128 x) { return fabsq(x); }
106+
inline __float128 copysign(__float128 x, __float128 y) { return copysignq(x, y); }
107+
inline __float128 nextafter(__float128 x, __float128 y) { return nextafterq(x, y); }
108+
inline __float128 nexttoward(__float128 x, long double y) { return nextafterq(x, static_cast<__float128>(y)); }
109+
110+
/* Float Exponents */
111+
112+
inline int ilogb(__float128 x) { return ilogbq(x); }
113+
inline __float128 frexp (__float128 x, int* exp) { return frexpq (x, exp); }
114+
inline __float128 ldexp (__float128 x, int exp) { return ldexpq (x, exp); }
115+
inline __float128 scalbn (__float128 x, int exp) { return scalbnq (x, exp); }
116+
inline __float128 scalbln(__float128 x, long exp) { return scalblnq(x, exp); }
117+
118+
/* Arithmetic */
119+
120+
inline __float128 fmax(__float128 x, __float128 y) { return fmaxq(x, y); }
121+
inline __float128 fmin(__float128 x, __float128 y) { return fminq(x, y); }
122+
inline __float128 fdim(__float128 x, __float128 y) { return fdimq(x, y); }
123+
inline __float128 fma(__float128 x, __float128 y, __float128 z) { return fmaq(x, y, z); }
124+
inline __float128 sqrt(__float128 x) { return sqrtq(x); }
125+
inline __float128 cbrt(__float128 x) { return cbrtq(x); }
126+
inline __float128 hypot(__float128 x, __float128 y) { return hypotq(x, y); }
127+
128+
/* Remainder and Modulus */
129+
130+
inline __float128 fmod(__float128 x, __float128 y) { return fmodq(x, y); }
131+
inline __float128 remainder(__float128 x, __float128 y) { return remainderq(x, y); }
132+
inline __float128 remquo(__float128 x, __float128 y, int* quo) { return remquoq(x, y, quo); }
133+
134+
/* Rounding */
135+
136+
inline __float128 modf(__float128 x, __float128* integral_part) { return modfq(x, integral_part); }
137+
inline __float128 trunc(__float128 x) { return truncq(x); }
138+
inline __float128 floor(__float128 x) { return floorq(x); }
139+
inline __float128 ceil (__float128 x) { return ceilq (x); }
140+
inline __float128 rint (__float128 x) { return rintq (x); }
141+
inline __float128 round(__float128 x) { return roundq(x); }
142+
inline long lrint (__float128 x) { return lrintq (x); }
143+
inline long lround(__float128 x) { return lroundq(x); }
144+
inline long long llrint (__float128 x) { return llrintq (x); }
145+
inline long long llround(__float128 x) { return llroundq(x); }
146+
inline __float128 nearbyint(__float128 x) { return nearbyintq(x); }
147+
148+
/* Logarithms and Exponents */
149+
150+
inline __float128 log (__float128 x) { return logq (x); }
151+
inline __float128 log1p(__float128 x) { return log1pq(x); }
152+
inline __float128 logb (__float128 x) { return logbq (x); }
153+
inline __float128 log2 (__float128 x) { return log2q (x); }
154+
inline __float128 log10(__float128 x) { return log10q(x); }
155+
inline __float128 exp (__float128 x) { return expq (x); }
156+
inline __float128 expm1(__float128 x) { return expm1q(x); }
157+
inline __float128 exp2 (__float128 x) { return exp2q (x); }
158+
inline __float128 pow(__float128 x, __float128 y) { return powq(x, y); }
159+
160+
/* Trigonometry */
161+
162+
inline __float128 sin (__float128 x) { return sinq (x); }
163+
inline __float128 cos (__float128 x) { return cosq (x); }
164+
inline __float128 tan (__float128 x) { return tanq (x); }
165+
inline __float128 asin (__float128 x) { return asinq (x); }
166+
inline __float128 acos (__float128 x) { return acosq (x); }
167+
inline __float128 atan (__float128 x) { return atanq (x); }
168+
inline __float128 sinh(__float128 x) { return sinhq(x); }
169+
inline __float128 cosh(__float128 x) { return coshq(x); }
170+
inline __float128 tanh(__float128 x) { return tanhq(x); }
171+
inline __float128 asinh(__float128 x) { return asinhq(x); }
172+
inline __float128 acosh(__float128 x) { return acoshq(x); }
173+
inline __float128 atanh(__float128 x) { return atanhq(x); }
174+
inline __float128 atan2(__float128 y, __float128 x) { return atan2q(y, x); }
175+
inline void sincos(__float128 x, __float128* p_sin, __float128* p_cos) { sincosq(x, p_sin, p_cos); }
176+
177+
/* Transcendental Functions */
178+
179+
inline __float128 erf (__float128 x) { return erfq (x); }
180+
inline __float128 erfc(__float128 x) { return erfcq(x); }
181+
inline __float128 lgamma(__float128 x) { return lgammaq(x); }
182+
inline __float128 tgamma(__float128 x) { return tgammaq(x); }
183+
184+
#endif /* QUADMATH_CPP_H */

test/CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "./bin")
1616
set(CMAKE_CXX_STANDARD 11)
1717

1818
# Compiler Flags
19-
set(OPT_FLAG -O2 -g)
19+
set(OPT_FLAG -O0 -g)
2020

2121
# Source Files
2222
file(GLOB_RECURSE SRC_FILES "${SRC_DIR}/*.c" "${SRC_DIR}/*.cpp")
@@ -26,8 +26,8 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "./bin")
2626
# Compile Options
2727

2828
target_compile_options(${PROJECT_NAME} PRIVATE
29-
${OPT_FLAG}
30-
-Wall -Wextra -Wpedantic -Wshadow -Wfloat-conversion -Wconversion -Wformat=2
29+
${OPT_FLAG} -fsignaling-nans
30+
-Wall -Wextra -Wshadow -Wfloat-conversion -Wconversion -Wformat=2
3131
)
3232

3333
target_link_libraries(${PROJECT_NAME} PRIVATE "quadmath")

0 commit comments

Comments
 (0)