Geogram  Version 1.9.1
A programming library of geometric algorithms
numeric.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2000-2022 Inria
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * * Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * * Neither the name of the ALICE Project-Team nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  * Contact: Bruno Levy
30  *
31  * https://www.inria.fr/fr/bruno-levy
32  *
33  * Inria,
34  * Domaine de Voluceau,
35  * 78150 Le Chesnay - Rocquencourt
36  * FRANCE
37  *
38  */
39 
40 #ifndef GEOGRAM_BASIC_NUMERIC
41 #define GEOGRAM_BASIC_NUMERIC
42 
43 #include <geogram/basic/common.h>
44 #include <cmath>
45 #include <float.h>
46 #include <limits.h>
47 #include <algorithm> // for std::min / std::max
48 #include <stdint.h>
49 #include <limits>
50 
51 #ifndef M_PI
55 #define M_PI 3.14159265358979323846
56 #endif
57 
63 namespace GEO {
64 
68  enum Sign {
70  NEGATIVE = -1,
72  ZERO = 0,
74  POSITIVE = 1
75  };
76 
89  template <class T>
90  inline Sign geo_sgn(const T& x) {
91  return (x > 0) ? POSITIVE : (
92  (x < 0) ? NEGATIVE : ZERO
93  );
94  }
95 
105  template <class T>
106  inline Sign geo_cmp(const T& a, const T& b) {
107  return Sign((a > b) * POSITIVE + (a < b) * NEGATIVE);
108  }
109 
117  namespace Numeric {
118 
120  typedef void* pointer;
121 
123  typedef int8_t int8;
124 
126  typedef int16_t int16;
127 
129  typedef int32_t int32;
130 
132  typedef int64_t int64;
133 
135  typedef uint8_t uint8;
136 
138  typedef uint16_t uint16;
139 
141  typedef uint32_t uint32;
142 
144  typedef uint64_t uint64;
145 
147  typedef float float32;
148 
150  typedef double float64;
151 
155  inline float32 max_float32() {
156  return std::numeric_limits<float32>::max();
157  }
158 
162  inline float32 min_float32() {
163  // Note: numeric_limits<>::min() is not
164  // what we want (it returns the smallest
165  // positive non-denormal).
166  return -max_float32();
167  }
168 
172  inline float64 max_float64() {
173  return std::numeric_limits<float64>::max();
174  }
175 
179  inline float64 min_float64() {
180  // Note: numeric_limits<>::min() is not
181  // what we want (it returns the smallest
182  // positive non-denormal).
183  return -max_float64();
184  }
185 
189  bool GEOGRAM_API is_nan(float32 x);
190 
194  bool GEOGRAM_API is_nan(float64 x);
195 
199  void GEOGRAM_API random_reset();
200 
204  int32 GEOGRAM_API random_int32();
205 
209  float32 GEOGRAM_API random_float32();
210 
214  float64 GEOGRAM_API random_float64();
215 
230  template <class T, bool is_numeric>
231  struct LimitsHelper : std::numeric_limits<T> {
232  };
233 
241  template <class T>
242  struct LimitsHelper<T, true> : std::numeric_limits<T> {
244  static const size_t size = sizeof(T);
246  static const size_t numbits = 8 * sizeof(T);
247  };
248 
258  template <class T>
259  struct Limits :
260  LimitsHelper<T, std::numeric_limits<T>::is_specialized> {
261  };
262 
267  template <class T> inline void optimize_number_representation(T& x) {
268  geo_argused(x);
269  }
270 
278  template <class T> inline Sign ratio_compare(
279  const T& a_num, const T& a_denom, const T& b_num, const T& b_denom
280  ) {
281  if(a_denom == b_denom) {
282  return Sign(geo_cmp(a_num,b_num)*geo_sgn(a_denom));
283  }
284  return Sign(
285  geo_cmp(a_num*b_denom, b_num*a_denom) *
286  geo_sgn(a_denom) * geo_sgn(b_denom)
287  );
288  }
289  }
290 
291  /************************************************************************/
292 
293 
300  template <class T>
301  inline T geo_sqr(T x) {
302  return x * x;
303  }
304 
313  template <class T>
314  inline void geo_clamp(T& x, T min, T max) {
315  if(x < min) {
316  x = min;
317  } else if(x > max) {
318  x = max;
319  }
320  }
321 
330 
334  inline index_t max_index_t() {
335  return std::numeric_limits<index_t>::max();
336  }
337 
344 
349  return std::numeric_limits<signed_index_t>::max();
350  }
351 
356  return std::numeric_limits<signed_index_t>::min();
357  }
358 
364 
368  inline double round(double x) {
369  return ((x - floor(x)) > 0.5 ? ceil(x) : floor(x));
370  }
371 
372  /************************************************************************/
373 
379  static constexpr index_t NO_INDEX = index_t(-1);
380 
381  /************************************************************************/
382 }
383 
384 #endif
unsigned char geo_coord_index_t
Represents dimension (e.g. 3 for 3d, 4 for 4d ...).
Definition: defs.h:105
unsigned int geo_index_t
Represents indices.
Definition: defs.h:133
int geo_signed_index_t
Represents possibly negative indices.
Definition: defs.h:139
Common include file, providing basic definitions. Should be included before anything else by all head...
float float32
Definition: numeric.h:147
uint8_t uint8
Definition: numeric.h:135
uint64_t uint64
Definition: numeric.h:144
int8_t int8
Definition: numeric.h:123
double float64
Definition: numeric.h:150
int32_t int32
Definition: numeric.h:129
void * pointer
Definition: numeric.h:120
float64 max_float64()
Gets 64 bits float maximum positive value.
Definition: numeric.h:172
float32 max_float32()
Gets 32 bits float maximum positive value.
Definition: numeric.h:155
uint16_t uint16
Definition: numeric.h:138
float32 random_float32()
Returns a 32 bits float between 0 and 1.
uint32_t uint32
Definition: numeric.h:141
Sign ratio_compare(const T &a_num, const T &a_denom, const T &b_num, const T &b_denom)
Compares two rational numbers given as separate numerators and denominators.
Definition: numeric.h:278
float64 random_float64()
Returns a 64 bits float between 0 and 1.
void optimize_number_representation(T &x)
place holder for optimizing internal number representation
Definition: numeric.h:267
void random_reset()
Resets the random number generator.
int32 random_int32()
Returns a 32 bits integer between 0 and RAND_MAX.
float64 min_float64()
Gets 64 bits float minimum negative value.
Definition: numeric.h:179
float32 min_float32()
Gets 32 bits float minimum negative value.
Definition: numeric.h:162
bool is_nan(float32 x)
Checks whether a 32 bits float is "not a number".
int16_t int16
Definition: numeric.h:126
int64_t int64
Definition: numeric.h:132
Global Vorpaline namespace.
Definition: basic.h:55
signed_index_t min_signed_index_t()
Gets the minimum negative value of type signed_index_t.
Definition: numeric.h:355
T geo_sqr(T x)
Gets the square value of a value.
Definition: numeric.h:301
index_t max_index_t()
Gets the maximum positive value of type index_t.
Definition: numeric.h:334
void geo_argused(const T &)
Suppresses compiler warnings about unused parameters.
Definition: argused.h:60
geo_signed_index_t signed_index_t
The type for storing and manipulating indices differences.
Definition: numeric.h:343
void geo_clamp(T &x, T min, T max)
Clamps a value to a range.
Definition: numeric.h:314
Sign geo_sgn(const T &x)
Gets the sign of a value.
Definition: numeric.h:90
geo_index_t index_t
The type for storing and manipulating indices.
Definition: numeric.h:329
Sign
Integer constants that represent the sign of a value.
Definition: numeric.h:68
@ ZERO
Definition: numeric.h:72
@ NEGATIVE
Definition: numeric.h:70
@ POSITIVE
Definition: numeric.h:74
Sign geo_cmp(const T &a, const T &b)
Compares two values.
Definition: numeric.h:106
signed_index_t max_signed_index_t()
Gets the maximum positive value of type signed_index_t.
Definition: numeric.h:348
double round(double x)
Definition: numeric.h:368
geo_coord_index_t coord_index_t
The type for storing coordinate indices, and iterating on the coordinates of a point.
Definition: numeric.h:363
Limits helper class that extends std::numeric_limits.
Definition: numeric.h:231
Extends std::numeric_limits with additional information.
Definition: numeric.h:260