/src/geos/src/util/math.cpp
Line | Count | Source |
1 | | /********************************************************************** |
2 | | * |
3 | | * GEOS - Geometry Engine Open Source |
4 | | * http://geos.osgeo.org |
5 | | * |
6 | | * Copyright (C) 2006 Refractions Research |
7 | | * |
8 | | * This is free software; you can redistribute and/or modify it under |
9 | | * the terms of the GNU Lesser General Public Licence as published |
10 | | * by the Free Software Foundation. |
11 | | * See the COPYING file for more information. |
12 | | * |
13 | | **********************************************************************/ |
14 | | |
15 | | #include <geos/export.h> |
16 | | #include <geos/util.h> |
17 | | #include <cmath> |
18 | | |
19 | | namespace geos { |
20 | | namespace util { // geos.util |
21 | | |
22 | | /* |
23 | | * Symmetric Rounding Algorithm - equivalent to C99 round() |
24 | | */ |
25 | | double GEOS_DLL |
26 | | sym_round(double val) |
27 | 0 | { |
28 | 0 | double n; |
29 | 0 | double f = std::fabs(std::modf(val, &n)); |
30 | 0 | if(val >= 0) { |
31 | 0 | if(f < 0.5) { |
32 | 0 | return std::floor(val); |
33 | 0 | } |
34 | 0 | else if(f > 0.5) { |
35 | 0 | return std::ceil(val); |
36 | 0 | } |
37 | 0 | else { |
38 | 0 | return (n + 1.0); |
39 | 0 | } |
40 | 0 | } |
41 | 0 | else { |
42 | 0 | if(f < 0.5) { |
43 | 0 | return std::ceil(val); |
44 | 0 | } |
45 | 0 | else if(f > 0.5) { |
46 | 0 | return std::floor(val); |
47 | 0 | } |
48 | 0 | else { |
49 | 0 | return (n - 1.0); |
50 | 0 | } |
51 | 0 | } |
52 | 0 | } |
53 | | |
54 | | /* |
55 | | * Asymmetric Rounding Algorithm - equivalent to Java Math.round() |
56 | | */ |
57 | | double GEOS_DLL |
58 | | java_math_round(double val) |
59 | 27.5M | { |
60 | 27.5M | double n; |
61 | 27.5M | double f = std::fabs(std::modf(val, &n)); |
62 | | |
63 | 27.5M | if(val >= 0) { |
64 | 25.6M | if(f < 0.5) { |
65 | 22.9M | return std::floor(val); |
66 | 22.9M | } |
67 | 2.69M | else if(f > 0.5) { |
68 | 2.68M | return std::ceil(val); |
69 | 2.68M | } |
70 | 11.9k | else { |
71 | 11.9k | return (n + 1.0); |
72 | 11.9k | } |
73 | 25.6M | } |
74 | 1.86M | else { |
75 | 1.86M | if(f < 0.5) { |
76 | 965k | return std::ceil(val); |
77 | 965k | } |
78 | 894k | else if(f > 0.5) { |
79 | 28.6k | return std::floor(val); |
80 | 28.6k | } |
81 | 865k | else { |
82 | 865k | return n; |
83 | 865k | } |
84 | 1.86M | } |
85 | 27.5M | } // java_math_round |
86 | | |
87 | | /* |
88 | | * Implementation of rint() |
89 | | */ |
90 | | double |
91 | | rint_vc(double val) |
92 | 0 | { |
93 | 0 | double n; |
94 | 0 | double f = std::fabs(std::modf(val, &n)); |
95 | 0 | if(val >= 0) { |
96 | 0 | if(f < 0.5) { |
97 | 0 | return std::floor(val); |
98 | 0 | } |
99 | 0 | else if(f > 0.5) { |
100 | 0 | return std::ceil(val); |
101 | 0 | } |
102 | 0 | else { |
103 | 0 | return(std::floor(n / 2) == n / 2) ? n : n + 1.0; |
104 | 0 | } |
105 | 0 | } |
106 | 0 | else { |
107 | 0 | if(f < 0.5) { |
108 | 0 | return std::ceil(val); |
109 | 0 | } |
110 | 0 | else if(f > 0.5) { |
111 | 0 | return std::floor(val); |
112 | 0 | } |
113 | 0 | else { |
114 | 0 | return(std::floor(n / 2) == n / 2) ? n : n - 1.0; |
115 | 0 | } |
116 | 0 | } |
117 | 0 | } |
118 | | |
119 | | |
120 | | double GEOS_DLL |
121 | | clamp(double x, double min, double max) |
122 | 0 | { |
123 | 0 | if (x < min) return min; |
124 | 0 | if (x > max) return max; |
125 | 0 | return x; |
126 | 0 | } |
127 | | |
128 | | |
129 | | } // namespace geos.util |
130 | | } // namespace geos |
131 | | |