Panda3D
Loading...
Searching...
No Matches
nearly_zero.h
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file nearly_zero.h
10 * @author drose
11 * @date 2000-03-08
12 */
13
14#ifndef NEARLY_ZERO_H
15#define NEARLY_ZERO_H
16
17#include "dtoolbase.h"
18
19// The following two functions are defined just to make the NEARLY_ZERO()
20// macro work. They each return a suitable nearly-zero value for their
21// corresponding numeric type.
22
23// Note that declaring these small numeric values first as a static const
24// identifier, and then returning the value of that identifier, seems to lead
25// to compilation errors (at least in VC7) in which sometimes
26// IS_THRESHOLD_COMPEQ(a, a, get_nearly_zero_value(a)) != 0.
27constexpr double
28get_nearly_zero_value(double) {
29 return 1.0e-12;
30}
31
32constexpr float
33get_nearly_zero_value(float) {
34 return 1.0e-6f;
35}
36
37constexpr int
38get_nearly_zero_value(int) {
39 // This is a bit silly, but we should nevertheless define it in case it is
40 // called for an integer type.
41 return 0;
42}
43
44
45// IS_THRESHOLD_ZERO(value, threshold) returns true if the value is within
46// threshold of zero.
47#define IS_THRESHOLD_ZERO(value, threshold) \
48 ((value) < (threshold) && (value) > -(threshold))
49
50// IS_THRESHOLD_EQUAL(value1, value2, threshold) returns true if the two
51// values are within threshold of each other.
52#define IS_THRESHOLD_EQUAL(value1, value2, threshold) \
53 (IS_THRESHOLD_ZERO((value1) - (value2), threshold))
54
55// IS_THRESHOLD_COMPEQ(value1, value2, threshold) returns true if the two
56// values are equal within threshold tolerance. Unlike IS_THRESHOLD_EQUAL,
57// the transitive principle is guaranteed: IS_THRESHOLD_COMPEQ(a, b, t) &&
58// IS_THRESHOLD_COMPEQ(b, c, t) implies IS_THRESHOLD_COMPEQ(a, c, t).
59#define IS_THRESHOLD_COMPEQ(value1, value2, threshold) \
60 (cfloor(value1 / threshold + 0.5f) == cfloor(value2 / threshold + 0.5f))
61
62// NEARLY_ZERO(float) returns a number that is considered to be so close to
63// zero as not to matter for a float. NEARLY_ZERO(double) returns a similar,
64// smaller number for a double.
65#define NEARLY_ZERO(FLOATTYPE) (get_nearly_zero_value((FLOATTYPE)0))
66
67// IS_NEARLY_ZERO(value) returns true if the value is very close to zero.
68#define IS_NEARLY_ZERO(value) \
69 (IS_THRESHOLD_ZERO(value, get_nearly_zero_value(value)))
70
71// IS_NEARLY_EQUAL(value1, value2) returns true if the two values are very
72// close to each other.
73#define IS_NEARLY_EQUAL(value1, value2) \
74 (IS_THRESHOLD_EQUAL(value1, value2, get_nearly_zero_value(value1)))
75
76
77// MAYBE_ZERO(value) returns 0 if the value is nearly zero, and the value
78// itself otherwise.
79#define MAYBE_ZERO(value) \
80 (IS_NEARLY_ZERO(value) ? 0 : (value))
81
82
83#endif
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.