1 /*--------------------------------------------------------------------
2  *
3  * Copyright (c) 1991-2021 by the GMT Team (https://www.generic-mapping-tools.org/team.html)
4  * See LICENSE.TXT file for copying and redistribution conditions.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation; version 3 or any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * Contact info: www.generic-mapping-tools.org
16  *--------------------------------------------------------------------*/
17 /*
18  * gmt_common_math.h declares shared math functions
19  *
20  * Author:  Florian Wobbe
21  * Date:    10-MAR-2012
22  * Version: 5
23  */
24 
25 /*!
26  * \file gmt_common_math.h
27  * \brief declares shared math functions
28  */
29 
30 #pragma once
31 #ifndef GMT_COMMON_MATH_H
32 #define GMT_COMMON_MATH_H
33 
34 #ifdef __cplusplus      /* Basic C++ support */
35 extern "C" {
36 #endif
37 
38 	/* CMake definitions: This must be first! */
39 #include "gmt_config.h"
40 
41 	/* Declaration modifiers for DLL support (MSC et al) */
42 #include "declspec.h"
43 #include <stdint.h>
44 #include <stdbool.h>
45 
46 	/* int32_abs function that works with int32_t */
47 #if defined(SIZEOF_INT) && SIZEOF_INT == 4 && defined(HAVE_ABS)
48 #	define int32_abs abs
49 #elif defined(SIZEOF_LONG) && SIZEOF_LONG == 4
50 #	define int32_abs labs
51 #else
52 #	define int32_abs(x) ((int32_t)(((x) >= 0) ? (x) : -(x)))
53 #endif
54 
55 	/* int64_abs function that works with int64_t */
56 #if defined(_WIN64)
57 #	define int64_abs _abs64
58 #elif defined(SIZEOF_INT) && SIZEOF_INT == 8 && defined(HAVE_ABS)
59 #	define int64_abs abs
60 #elif defined(SIZEOF_LONG) && SIZEOF_LONG == 8
61 #	define int64_abs labs
62 #elif defined(SIZEOF_LONG_LONG) && SIZEOF_LONG_LONG == 8 && defined(HAVE_LLABS)
63 #	define int64_abs llabs
64 #else
65 #	define int64_abs(x) ((int64_t)(((x) >= 0) ? (x) : -(x)))
66 #endif
67 
68 #ifdef __CYGWIN__	/* See http://gmt.soest.hawaii.edu/boards/1/topics/5428 */
69 #ifdef __x86_64
70 #define lrint(x) ((long int)(int)lrint(x))
71 #endif
72 #endif
73 
74 	/* Limit casting to one place (here) for dropping lrint output to signed or unsigned ints */
75 #define irint(x) ((int)lrint(x))
76 #define urint(x) ((unsigned int)lrint(x))
77 #define irintf(x) ((int)lrintf(x))
78 #define urintf(x) ((unsigned int)lrintf(x))
79 
80 	/* Safe rounding of float and double to signed and unsigned 64 bit ints */
81 #if defined(SIZEOF_INT) && SIZEOF_LONG == 8
82 #	define irint64(x) lrint(x)
83 #	define urint64(x) ((uint64_t)lrint(x))
84 #	define irint64f(x) lrintf(x)
85 #	define urint64f(x) ((uint64_t)lrintf(x))
86 #else /* SIZEOF_LONG_LONG == 8 by ISO C definition */
87 #	define irint64(x) llrint(x)
88 #	define urint64(x) ((uint64_t)llrint(x))
89 #	define irint64f(x) llrintf(x)
90 #	define urint64f(x) ((uint64_t)llrintf(x))
91 #endif
92 
93 	EXTERN_MSC bool floatAlmostEqualUlpsAndAbs(float A, float B, float maxDiff, int maxUlpsDiff);
94 	EXTERN_MSC bool doubleAlmostEqualUlpsAndAbs(double A, double B, double maxDiff, int maxUlpsDiff);
95 	EXTERN_MSC bool floatAlmostEqualUlps(float A, float B, int maxUlpsDiff);
96 	EXTERN_MSC bool doubleAlmostEqualUlps(double A, double B, int maxUlpsDiff);
97 
98 #	define floatAlmostEqual(A, B) (floatAlmostEqualUlps(A, B, 5))
99 #	define doubleAlmostEqual(A, B) (doubleAlmostEqualUlps(A, B, 5))
100 #	define floatAlmostEqualZero(A, B) (floatAlmostEqualUlpsAndAbs(A, B, 5*FLT_EPSILON, 5))
101 #	define doubleAlmostEqualZero(A, B) (doubleAlmostEqualUlpsAndAbs(A, B, 5*DBL_EPSILON, 5))
102 
103 #ifdef __cplusplus
104 }
105 #endif
106 
107 #endif /* !GMT_COMMON_MATH_H */
108