EstervQrCode 2.0.0
Library for qr code manipulation
Loading...
Searching...
No Matches
fast_math.hpp
1/*M///////////////////////////////////////////////////////////////////////////////////////
2//
3// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4//
5// By downloading, copying, installing or using the software you agree to this license.
6// If you do not agree to this license, do not download, install,
7// copy or use the software.
8//
9//
10// License Agreement
11// For Open Source Computer Vision Library
12//
13// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
14// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
15// Copyright (C) 2013, OpenCV Foundation, all rights reserved.
16// Copyright (C) 2015, Itseez Inc., all rights reserved.
17// Third party copyrights are property of their respective owners.
18//
19// Redistribution and use in source and binary forms, with or without modification,
20// are permitted provided that the following conditions are met:
21//
22// * Redistribution's of source code must retain the above copyright notice,
23// this list of conditions and the following disclaimer.
24//
25// * Redistribution's in binary form must reproduce the above copyright notice,
26// this list of conditions and the following disclaimer in the documentation
27// and/or other materials provided with the distribution.
28//
29// * The name of the copyright holders may not be used to endorse or promote products
30// derived from this software without specific prior written permission.
31//
32// This software is provided by the copyright holders and contributors "as is" and
33// any express or implied warranties, including, but not limited to, the implied
34// warranties of merchantability and fitness for a particular purpose are disclaimed.
35// In no event shall the Intel Corporation or contributors be liable for any direct,
36// indirect, incidental, special, exemplary, or consequential damages
37// (including, but not limited to, procurement of substitute goods or services;
38// loss of use, data, or profits; or business interruption) however caused
39// and on any theory of liability, whether in contract, strict liability,
40// or tort (including negligence or otherwise) arising in any way out of
41// the use of this software, even if advised of the possibility of such damage.
42//
43//M*/
44
45#ifndef OPENCV_CORE_FAST_MATH_HPP
46#define OPENCV_CORE_FAST_MATH_HPP
47
48#include "opencv2/core/cvdef.h"
49
52
53/****************************************************************************************\
54* fast math *
55\****************************************************************************************/
56
57#ifdef __cplusplus
58# include <cmath>
59#else
60# ifdef __BORLANDC__
61# include <fastmath.h>
62# else
63# include <math.h>
64# endif
65#endif
66
67#if defined(__CUDACC__)
68 // nothing, intrinsics/asm code is not supported
69#else
70 #if ((defined _MSC_VER && defined _M_X64) \
71 || (defined __GNUC__ && defined __SSE2__)) \
72 && !defined(OPENCV_SKIP_INCLUDE_EMMINTRIN_H)
73 #include <emmintrin.h>
74 #endif
75
76 #if defined __PPC64__ && defined __GNUC__ && defined _ARCH_PWR8 \
77 && !defined(OPENCV_SKIP_INCLUDE_ALTIVEC_H)
78 #include <altivec.h>
79 #undef vector
80 #undef bool
81 #undef pixel
82 #endif
83
84 #if defined(CV_INLINE_ROUND_FLT)
85 // user-specified version
86 // CV_INLINE_ROUND_DBL should be defined too
87 #elif defined __GNUC__ && defined __arm__ && (defined __ARM_PCS_VFP || defined __ARM_VFPV3__ || defined __ARM_NEON) && !defined __SOFTFP__
88 // 1. general scheme
89 #define ARM_ROUND(_value, _asm_string) \
90 int res; \
91 float temp; \
92 CV_UNUSED(temp); \
93 __asm__(_asm_string : [res] "=r" (res), [temp] "=w" (temp) : [value] "w" (_value)); \
94 return res
95 // 2. version for double
96 #ifdef __clang__
97 #define CV_INLINE_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %[value] \n vmov %[res], %[temp]")
98 #else
99 #define CV_INLINE_ROUND_DBL(value) ARM_ROUND(value, "vcvtr.s32.f64 %[temp], %P[value] \n vmov %[res], %[temp]")
100 #endif
101 // 3. version for float
102 #define CV_INLINE_ROUND_FLT(value) ARM_ROUND(value, "vcvtr.s32.f32 %[temp], %[value]\n vmov %[res], %[temp]")
103 #elif defined __PPC64__ && defined __GNUC__ && defined _ARCH_PWR8
104 // P8 and newer machines can convert fp32/64 to int quickly.
105 #define CV_INLINE_ROUND_DBL(value) \
106 int out; \
107 double temp; \
108 __asm__( "fctiw %[temp],%[in]\n\tmfvsrwz %[out],%[temp]\n\t" : [out] "=r" (out), [temp] "=d" (temp) : [in] "d" ((double)(value)) : ); \
109 return out;
110
111 // FP32 also works with FP64 routine above
112 #define CV_INLINE_ROUND_FLT(value) CV_INLINE_ROUND_DBL(value)
113 #endif
114
115 #ifdef CV_INLINE_ISINF_FLT
116 // user-specified version
117 // CV_INLINE_ISINF_DBL should be defined too
118 #elif defined __PPC64__ && defined _ARCH_PWR9 && defined(scalar_test_data_class)
119 #define CV_INLINE_ISINF_DBL(value) return scalar_test_data_class(value, 0x30);
120 #define CV_INLINE_ISINF_FLT(value) CV_INLINE_ISINF_DBL(value)
121 #endif
122
123 #ifdef CV_INLINE_ISNAN_FLT
124 // user-specified version
125 // CV_INLINE_ISNAN_DBL should be defined too
126 #elif defined __PPC64__ && defined _ARCH_PWR9 && defined(scalar_test_data_class)
127 #define CV_INLINE_ISNAN_DBL(value) return scalar_test_data_class(value, 0x40);
128 #define CV_INLINE_ISNAN_FLT(value) CV_INLINE_ISNAN_DBL(value)
129 #endif
130
131 #if !defined(OPENCV_USE_FASTMATH_BUILTINS) \
132 && ( \
133 defined(__x86_64__) || defined(__i686__) \
134 || defined(__arm__) \
135 || defined(__PPC64__) \
136 )
137 /* Let builtin C math functions when available. Dedicated hardware is available to
138 round and convert FP values. */
139 #define OPENCV_USE_FASTMATH_BUILTINS 1
140 #endif
141
142 /* Enable builtin math functions if possible, desired, and available.
143 Note, not all math functions inline equally. E.g lrint will not inline
144 without the -fno-math-errno option. */
145 #if defined(CV_ICC)
146 // nothing
147 #elif defined(OPENCV_USE_FASTMATH_BUILTINS) && OPENCV_USE_FASTMATH_BUILTINS
148 #if defined(__clang__)
149 #define CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
150 #if !defined(CV_INLINE_ISNAN_DBL) && __has_builtin(__builtin_isnan)
151 #define CV_INLINE_ISNAN_DBL(value) return __builtin_isnan(value);
152 #endif
153 #if !defined(CV_INLINE_ISNAN_FLT) && __has_builtin(__builtin_isnan)
154 #define CV_INLINE_ISNAN_FLT(value) return __builtin_isnan(value);
155 #endif
156 #if !defined(CV_INLINE_ISINF_DBL) && __has_builtin(__builtin_isinf)
157 #define CV_INLINE_ISINF_DBL(value) return __builtin_isinf(value);
158 #endif
159 #if !defined(CV_INLINE_ISINF_FLT) && __has_builtin(__builtin_isinf)
160 #define CV_INLINE_ISINF_FLT(value) return __builtin_isinf(value);
161 #endif
162 #elif defined(__GNUC__)
163 #define CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS
164 #if !defined(CV_INLINE_ISNAN_DBL)
165 #define CV_INLINE_ISNAN_DBL(value) return __builtin_isnan(value);
166 #endif
167 #if !defined(CV_INLINE_ISNAN_FLT)
168 #define CV_INLINE_ISNAN_FLT(value) return __builtin_isnanf(value);
169 #endif
170 #if !defined(CV_INLINE_ISINF_DBL)
171 #define CV_INLINE_ISINF_DBL(value) return __builtin_isinf(value);
172 #endif
173 #if !defined(CV_INLINE_ISINF_FLT)
174 #define CV_INLINE_ISINF_FLT(value) return __builtin_isinff(value);
175 #endif
176 #elif defined(_MSC_VER)
177 #if !defined(CV_INLINE_ISNAN_DBL)
178 #define CV_INLINE_ISNAN_DBL(value) return isnan(value);
179 #endif
180 #if !defined(CV_INLINE_ISNAN_FLT)
181 #define CV_INLINE_ISNAN_FLT(value) return isnan(value);
182 #endif
183 #if !defined(CV_INLINE_ISINF_DBL)
184 #define CV_INLINE_ISINF_DBL(value) return isinf(value);
185 #endif
186 #if !defined(CV_INLINE_ISINF_FLT)
187 #define CV_INLINE_ISINF_FLT(value) return isinf(value);
188 #endif
189 #endif
190 #endif
191
192#endif // defined(__CUDACC__)
193
199CV_INLINE int
200cvRound( double value )
201{
202#if defined CV_INLINE_ROUND_DBL
203 CV_INLINE_ROUND_DBL(value);
204#elif ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __SSE2__)) && !defined(__CUDACC__)
205 __m128d t = _mm_set_sd( value );
206 return _mm_cvtsd_si32(t);
207#elif defined _MSC_VER && defined _M_IX86
208 int t;
209 __asm
210 {
211 fld value;
212 fistp t;
213 }
214 return t;
215#elif defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
216 defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
217 return (int)__builtin_lrint(value);
218#else
219 return (int)lrint(value);
220#endif
221}
222
223
232{
233#if defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
234 defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
235 return (int)__builtin_floor(value);
236#elif defined __loongarch64
237 int i;
238 double tmp;
239 __asm__ ("ftintrm.l.d %[tmp], %[in] \n\t"
240 "movfr2gr.d %[i], %[tmp] \n\t"
241 : [i] "=r" (i), [tmp] "=f" (tmp)
242 : [in] "f" (value)
243 :);
244 return i;
245#else
246 int i = (int)value;
247 return i - (i > value);
248#endif
249}
250
258CV_INLINE int cvCeil( double value )
259{
260#if defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
261 defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
262 return (int)__builtin_ceil(value);
263#elif defined __loongarch64
264 int i;
265 double tmp;
266 __asm__ ("ftintrp.l.d %[tmp], %[in] \n\t"
267 "movfr2gr.d %[i], %[tmp] \n\t"
268 : [i] "=r" (i), [tmp] "=f" (tmp)
269 : [in] "f" (value)
270 :);
271 return i;
272#else
273 int i = (int)value;
274 return i + (i < value);
275#endif
276}
277
285{
286#if defined CV_INLINE_ISNAN_DBL
287 CV_INLINE_ISNAN_DBL(value);
288#else
289 Cv64suf ieee754;
290 ieee754.f = value;
291 return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) +
292 ((unsigned)ieee754.u != 0) > 0x7ff00000;
293#endif
294}
295
303{
304#if defined CV_INLINE_ISINF_DBL
305 CV_INLINE_ISINF_DBL(value);
306#elif defined(__x86_64__) || defined(_M_X64) || defined(__aarch64__) || defined(_M_ARM64) || defined(__PPC64__) || defined(__loongarch64)
307 Cv64suf ieee754;
308 ieee754.f = value;
309 return (ieee754.u & 0x7fffffffffffffff) ==
310 0x7ff0000000000000;
311#else
312 Cv64suf ieee754;
313 ieee754.f = value;
314 return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
315 (unsigned)ieee754.u == 0;
316#endif
317}
318
319#ifdef __cplusplus
320
322CV_INLINE int cvRound(float value)
323{
324#if defined CV_INLINE_ROUND_FLT
325 CV_INLINE_ROUND_FLT(value);
326#elif ((defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __SSE2__)) && !defined(__CUDACC__)
327 __m128 t = _mm_set_ss( value );
328 return _mm_cvtss_si32(t);
329#elif defined _MSC_VER && defined _M_IX86
330 int t;
331 __asm
332 {
333 fld value;
334 fistp t;
335 }
336 return t;
337#elif defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
338 defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
339 return (int)__builtin_lrintf(value);
340#else
341 return (int)lrintf(value);
342#endif
343}
344
346CV_INLINE int cvRound( int value )
347{
348 return value;
349}
350
352CV_INLINE int cvFloor( float value )
353{
354#if defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
355 defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
356 return (int)__builtin_floorf(value);
357#elif defined __loongarch__
358 int i;
359 float tmp;
360 __asm__ ("ftintrm.w.s %[tmp], %[in] \n\t"
361 "movfr2gr.s %[i], %[tmp] \n\t"
362 : [i] "=r" (i), [tmp] "=f" (tmp)
363 : [in] "f" (value)
364 :);
365 return i;
366#else
367 int i = (int)value;
368 return i - (i > value);
369#endif
370}
371
373CV_INLINE int cvFloor( int value )
374{
375 return value;
376}
377
379CV_INLINE int cvCeil( float value )
380{
381#if defined CV__FASTMATH_ENABLE_GCC_MATH_BUILTINS || \
382 defined CV__FASTMATH_ENABLE_CLANG_MATH_BUILTINS
383 return (int)__builtin_ceilf(value);
384#elif defined __loongarch__
385 int i;
386 float tmp;
387 __asm__ ("ftintrp.w.s %[tmp], %[in] \n\t"
388 "movfr2gr.s %[i], %[tmp] \n\t"
389 : [i] "=r" (i), [tmp] "=f" (tmp)
390 : [in] "f" (value)
391 :);
392 return i;
393#else
394 int i = (int)value;
395 return i + (i < value);
396#endif
397}
398
400CV_INLINE int cvCeil( int value )
401{
402 return value;
403}
404
406CV_INLINE int cvIsNaN( float value )
407{
408#if defined CV_INLINE_ISNAN_FLT
409 CV_INLINE_ISNAN_FLT(value);
410#else
411 Cv32suf ieee754;
412 ieee754.f = value;
413 return (ieee754.u & 0x7fffffff) > 0x7f800000;
414#endif
415}
416
418CV_INLINE int cvIsInf( float value )
419{
420#if defined CV_INLINE_ISINF_FLT
421 CV_INLINE_ISINF_FLT(value);
422#else
423 Cv32suf ieee754;
424 ieee754.f = value;
425 return (ieee754.u & 0x7fffffff) == 0x7f800000;
426#endif
427}
428
429#endif // __cplusplus
430
432
433#endif
int CvScalar value
Definition core_c.h:720
CV_INLINE int cvIsNaN(double value)
Determines if the argument is Not A Number.
Definition fast_math.hpp:284
CV_INLINE int cvIsInf(double value)
Determines if the argument is Infinity.
Definition fast_math.hpp:302
CV_INLINE int cvRound(double value)
Rounds floating-point number to the nearest integer.
Definition fast_math.hpp:200
CV_INLINE int cvCeil(double value)
Rounds floating-point number to the nearest integer not smaller than the original.
Definition fast_math.hpp:258
CV_INLINE int cvFloor(double value)
Rounds floating-point number to the nearest integer not larger than the original.
Definition fast_math.hpp:231
#define CV_INLINE
Definition cvdef.h:218
Definition cvdef.h:402
unsigned u
Definition cvdef.h:404
float f
Definition cvdef.h:405
Definition cvdef.h:410
double f
Definition cvdef.h:413
uint64 u
Definition cvdef.h:412