ReactOS 0.4.16-dev-1537-g4e425b5
math_helpers.h
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS api tests
3 * LICENSE: MIT (https://spdx.org/licenses/MIT)
4 * PURPOSE: Helpers for testing math functions
5 * COPYRIGHT: Copyright 2021-2025 Timo Kreuzer <timo.kreuzer@reactos.org>
6 */
7
8#pragma once
9
10#define _USE_MATH_DEFINES
11#include <math.h>
12#include <float.h>
13#include <stdint.h>
14#include <apitest.h>
15
16#if defined(__GNUC__) || defined(__clang__)
17#define __ATTRIBUTE_SSE2__ __attribute__((__target__("sse2")))
18#else
19#define __ATTRIBUTE_SSE2__
20#endif
21
22static
24double
26{
27 return *(double*)(&x);
28}
29
30static
34{
35 return *(UINT64*)(&x);
36}
37
38static
40float
42{
43 return *(float*)(&x);
44}
45
46static
50{
51 return *(UINT32*)(&x);
52}
53
54typedef struct _TESTENTRY_DBL
55{
56 unsigned long long x;
57 unsigned long long result;
59
60typedef struct _TESTENTRY_FLT
61{
62 unsigned long x;
63 unsigned long result;
65
66typedef struct _TESTENTRY_DBL_INT
67{
68 unsigned long long x;
69 int result;
71
72typedef struct _TESTENTRY_FLT_INT
73{
74 unsigned long x;
75 int result;
77
78typedef struct _PRECISE_VALUE
79{
80 double rounded;
81 double delta;
83
85{
86 double x;
90
91// Convert a double to a 64-bit integer with lexicographical ordering.
92static inline int64_t double_to_int64_lex(double d)
93{
94 union {
95 double d;
96 int64_t i;
97 } u;
98 u.d = d;
99 // For negative numbers, flip the ordering.
100 if (u.i < 0)
101 u.i = 0x8000000000000000LL - u.i;
102 return u.i;
103}
104
105// Convert a float to a 64-bit integer with lexicographical ordering.
106static inline int float_to_int_lex(float f)
107{
108 union {
109 float f;
110 int i;
111 } u;
112 u.f = f;
113 // For negative numbers, flip the ordering.
114 if (u.i < 0)
115 u.i = 0x80000000 - u.i;
116 return u.i;
117}
118
119// Returns the ULP difference between 'expected' and 'result'.
120// If result is greater than expected, the result is positive.
121// (If either value is NaN the function returns INT64_MAX.)
123{
124 // Exact equality: error is 0 ULPs.
125 if (expected == result)
126 return 0;
127
128 // If either value is not a number, return a sentinel.
129 if (_isnan(expected) || _isnan(result))
130 return INT64_MAX;
131
134
135 return i_result - i_expected;
136}
137
138static __inline int ulp_error_flt(float expected, float result)
139{
140 // Exact equality: error is 0 ULPs.
141 if (expected == result)
142 return 0;
143
144 // If either value is not a number, return a sentinel.
145 if (_isnan(expected) || _isnan(result))
146 return INT_MAX;
147
148 int i_expected = float_to_int_lex(expected);
150
151 return i_result - i_expected;
152}
153
155{
156 // Calculate error to expected rouned value as ULP
158 if ((error == INT64_MAX) || (error == 0))
159 return error;
160
161 // Check if the error has the same sign as the delta
162 if ((expected->delta >= 0.0) == (error >= 0))
163 {
164 // We have an error in the same direction as the delta.
165 // This means the error is correct as it is.
166 return error;
167 }
168 else
169 {
170 // We have an error in the opposite direction of the delta.
171 // This means the actual error is larger than the calculated error.
172 return (error < 0) ? error - 1 : error + 1;
173 }
174}
175
176#define ok_eq_dbl_exact_(file, line, func, ullx, z, ullexp) \
177 { \
178 double x = u64_to_dbl(ullx); \
179 unsigned long long ullz = dbl_to_u64(z); \
180 double exp = u64_to_dbl(ullexp); \
181 ok_(file, line)(ullz == ullexp, "Wrong value for '%s(%f)' [0x%016I64x], expected: %f [0x%016I64x], got: %f [0x%016I64x]\n", \
182 func, x, ullx, exp, ullexp, z, ullz); \
183 }
184#define ok_eq_dbl_exact(func, ullx, z, ullexp) ok_eq_dbl_exact_(__FILE__, __LINE__, func, ullx, z, ullexp)
185
186#define ok_eq_flt_exact_(file, line, func, ux, z, uexp) \
187 { \
188 float x = u32_to_flt(ux); \
189 unsigned int uz = flt_to_u32(z); \
190 float exp = u32_to_flt(uexp); \
191 ok_(file, line)(uz == uexp, "Wrong value for '%s(%f)' [0x%08x], expected: %f [0x%08x], got: %f [0x%08x]\n", \
192 func, x, (unsigned)ux, exp, (unsigned)uexp, z, (unsigned)uz); \
193 }
194#define ok_eq_flt_exact(func, ux, z, uexp) ok_eq_flt_exact_(__FILE__, __LINE__, func, ux, z, uexp)
unsigned long long UINT64
unsigned int UINT32
#define __inline
Definition: _wctype.cpp:15
UINT32 uint32_t
Definition: types.h:75
INT64 int64_t
Definition: types.h:72
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLfloat f
Definition: glext.h:7540
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
_Check_return_ __MINGW_NOTHROW _CRTIMP int __cdecl _isnan(_In_ double)
Definition: _isnan.c:13
i_result
Definition: intersect.cc:51
#define INT_MAX
Definition: intsafe.h:150
#define INT64_MAX
Definition: intsafe.h:159
#define d
Definition: ke_i.h:81
#define f
Definition: ke_i.h:83
static __inline double u64_to_dbl(UINT64 x)
Definition: math_helpers.h:25
struct _PRECISE_VALUE PRECISE_VALUE
struct _TESTENTRY_DBL TESTENTRY_DBL
static __inline UINT64 dbl_to_u64(double x)
Definition: math_helpers.h:33
struct _TESTENTRY_FLT TESTENTRY_FLT
static __inline float u32_to_flt(UINT32 x)
Definition: math_helpers.h:41
static __inline int64_t ulp_error_dbl(double expected, double result)
Definition: math_helpers.h:122
static __inline int64_t ulp_error_precise(PRECISE_VALUE *expected, double result)
Definition: math_helpers.h:154
static __inline UINT32 flt_to_u32(float x)
Definition: math_helpers.h:49
static int64_t double_to_int64_lex(double d)
Definition: math_helpers.h:92
struct _TESTENTRY_DBL_INT TESTENTRY_DBL_INT
struct _TESTENTRY_DBL_APPROX TESTENTRY_DBL_APPROX
static __inline int ulp_error_flt(float expected, float result)
Definition: math_helpers.h:138
static int float_to_int_lex(float f)
Definition: math_helpers.h:106
struct _TESTENTRY_FLT_INT TESTENTRY_FLT_INT
#define error(str)
Definition: mkdosfs.c:1605
BOOL expected
Definition: store.c:2063
PRECISE_VALUE expected
Definition: math_helpers.h:87
unsigned long long x
Definition: math_helpers.h:68
unsigned long long x
Definition: math_helpers.h:56
unsigned long long result
Definition: math_helpers.h:57
unsigned long x
Definition: math_helpers.h:74
unsigned long x
Definition: math_helpers.h:62
unsigned long result
Definition: math_helpers.h:63