GRASS GIS 8 Programmer's Manual 8.4.1(2025)-45ca3179ab
Loading...
Searching...
No Matches
xround.c
Go to the documentation of this file.
1#include <limits.h>
2#include <math.h>
3
4#include <grass/gis.h>
5#include <grass/raster.h>
6#include <grass/calc.h>
7
8/**********************************************************************
9round(x, step, start)
10
11 rounds x to nearest value in the sequence
12 y[i] = i * step + start
13
14**********************************************************************/
15
16/* i_round(x) rounds x to nearest value, handles negative correctly */
17
18static double i_round(double x, double step, double start)
19{
20 x -= start;
21 x /= step;
22 x = floor(x + 0.5);
23 x *= step;
24 x += start;
25 return x;
26}
27
28/**********************************************************************/
29
30int f_round(int argc, const int *argt, void **args)
31{
32 const DCELL *arg1 = args[1];
33 int i;
34
35 if (argc < 1)
36 return E_ARG_LO;
37 if (argc > 3)
38 return E_ARG_HI;
39
40 if (argc == 1 && argt[0] != CELL_TYPE)
41 return E_RES_TYPE;
42 if (argt[1] != DCELL_TYPE)
43 return E_ARG_TYPE;
44 if (argc > 1 && argt[2] != DCELL_TYPE)
45 return E_ARG_TYPE;
46 if (argc > 2 && argt[3] != DCELL_TYPE)
47 return E_ARG_TYPE;
48
49 if (argc == 1) {
50 CELL *res = args[0];
51
52 for (i = 0; i < columns; i++) {
53 if (IS_NULL_D(&arg1[i]))
54 SET_NULL_C(&res[i]);
55 else {
56 DCELL x = i_round(arg1[i], 1.0, 0.0);
57 if (x > 2147483647.0 || x < -2147483647.0)
58 SET_NULL_C(&res[i]);
59 else
60 res[i] = (CELL)x;
61 }
62 }
63 return 0;
64 }
65 else if (argc == 2) {
66 const DCELL *arg2 = args[2];
67
68 switch (argt[0]) {
69 case CELL_TYPE: {
70 CELL *res = args[0];
71
72 for (i = 0; i < columns; i++) {
73 if (IS_NULL_D(&arg1[i]))
74 SET_NULL_C(&res[i]);
75 else if (IS_NULL_D(&arg2[i]))
76 SET_NULL_C(&res[i]);
77 else {
78 DCELL x = i_round(arg1[i], arg2[i], 0.0);
79 if (x > 2147483647.0 || x < -2147483647.0)
80 SET_NULL_C(&res[i]);
81 else
82 res[i] = (CELL)x;
83 }
84 }
85 return 0;
86 }
87 case FCELL_TYPE: {
88 FCELL *res = args[0];
89
90 for (i = 0; i < columns; i++)
91 if (IS_NULL_D(&arg1[i]))
92 SET_NULL_F(&res[i]);
93 else if (IS_NULL_D(&arg2[i]))
94 SET_NULL_F(&res[i]);
95 else
96 res[i] = (FCELL)i_round(arg1[i], arg2[i], 0.0);
97 return 0;
98 }
99 case DCELL_TYPE: {
100 DCELL *res = args[0];
101
102 for (i = 0; i < columns; i++)
103 if (IS_NULL_D(&arg1[i]))
104 SET_NULL_D(&res[i]);
105 else if (IS_NULL_D(&arg2[i]))
106 SET_NULL_D(&res[i]);
107 else
108 res[i] = (DCELL)i_round(arg1[i], arg2[i], 0.0);
109 return 0;
110 }
111 default:
112 return E_INV_TYPE;
113 }
114 }
115 else if (argc == 3) {
116 const DCELL *arg2 = args[2];
117 const DCELL *arg3 = args[3];
118
119 switch (argt[0]) {
120 case CELL_TYPE: {
121 CELL *res = args[0];
122
123 for (i = 0; i < columns; i++) {
124 if (IS_NULL_D(&arg1[i]))
125 SET_NULL_C(&res[i]);
126 else if (IS_NULL_D(&arg2[i]))
127 SET_NULL_C(&res[i]);
128 else if (IS_NULL_D(&arg3[i]))
129 SET_NULL_C(&res[i]);
130 else {
131 DCELL x = i_round(arg1[i], arg2[i], arg3[i]);
132 if (x > 2147483647.0 || x < -2147483647.0)
133 SET_NULL_C(&res[i]);
134 else
135 res[i] = (CELL)x;
136 }
137 }
138 return 0;
139 }
140 case FCELL_TYPE: {
141 FCELL *res = args[0];
142
143 for (i = 0; i < columns; i++)
144 if (IS_NULL_D(&arg1[i]))
145 SET_NULL_F(&res[i]);
146 else if (IS_NULL_D(&arg2[i]))
147 SET_NULL_F(&res[i]);
148 else if (IS_NULL_D(&arg3[i]))
149 SET_NULL_F(&res[i]);
150 else
151 res[i] = (FCELL)i_round(arg1[i], arg2[i], arg3[i]);
152 return 0;
153 }
154 case DCELL_TYPE: {
155 DCELL *res = args[0];
156
157 for (i = 0; i < columns; i++)
158 if (IS_NULL_D(&arg1[i]))
159 SET_NULL_D(&res[i]);
160 else if (IS_NULL_D(&arg2[i]))
161 SET_NULL_D(&res[i]);
162 else if (IS_NULL_D(&arg3[i]))
163 SET_NULL_D(&res[i]);
164 else
165 res[i] = (DCELL)i_round(arg1[i], arg2[i], arg3[i]);
166 return 0;
167 }
168 default:
169 return E_INV_TYPE;
170 }
171 }
172 else
173 return E_WTF;
174}
175
176int c_round(int argc, int *argt)
177{
178 if (argc < 1)
179 return E_ARG_LO;
180 if (argc > 3)
181 return E_ARG_HI;
182
183 argt[0] = CELL_TYPE;
184 if (argc > 1 && argt[0] < argt[2])
185 argt[0] = argt[2];
186 if (argc > 2 && argt[0] < argt[3])
187 argt[0] = argt[3];
188
189 argt[1] = DCELL_TYPE;
190 if (argc > 1)
191 argt[2] = DCELL_TYPE;
192 if (argc > 2)
193 argt[3] = DCELL_TYPE;
194
195 return 0;
196}
int columns
Definition calc.c:11
#define x
int c_round(int argc, int *argt)
Definition xround.c:176
int f_round(int argc, const int *argt, void **args)
Definition xround.c:30