Vuo  2.4.1
VuoInteger.c
Go to the documentation of this file.
1
10#include "type.h"
11#include <limits.h>
12#include <string.h>
13
15#ifdef VUO_COMPILER
17 "title": "Integer",
18 "description": "A signed 64-bit integer.",
19 "keywords": [ "number", "signed" ],
20 "version": "1.0.0",
21 "dependencies": [
22 "VuoList_VuoInteger",
23 ],
24});
25#endif
27
33{
34 if (!js)
35 return 0;
36
37 json_type t = json_object_get_type(js);
38 if (t == json_type_int)
39 return json_object_get_int64(js);
40 else if (t == json_type_double)
41 {
42 double d = json_object_get_double(js);
43 if (d == -INFINITY)
44 return LLONG_MIN;
45 if (d == INFINITY)
46 return LLONG_MAX;
47 return d;
48 }
49 else
50 {
51 // Use strtold() instead of json_object_get_int64(),
52 // since the latter doesn't support JSON strings with scientific notation.
53 // Use `long double strtold()` instead of `double atof()`
54 // since `long double` can precisely represent the int64 max value, whereas `double` can't.
55 const char *s = json_object_get_string(js);
56 if (s)
57 return strtold(s, NULL);
58 else
59 return 0;
60 }
61}
62
68{
69 if (value == LLONG_MIN)
70 return json_object_new_double(-INFINITY);
71 else if (value == LLONG_MAX)
72 return json_object_new_double(INFINITY);
73 else
74 return json_object_new_int64(value);
75}
76
82{
84 char *summary = strdup(json_object_to_json_string_ext(js,JSON_C_TO_STRING_PLAIN));
85 json_object_put(js);
86 return summary;
87}
88
93{
94 unsigned long count = VuoListGetCount_VuoInteger(values);
95 if (count == 0)
96 {
97 *outputPosition = 0;
98 return 0;
99 }
100
101 VuoInteger *integers = VuoListGetData_VuoInteger(values);
102 VuoInteger min = LONG_MAX;
103 for (unsigned long i = 0; i < count; ++i)
104 if (integers[i] < min)
105 {
106 min = integers[i];
107 *outputPosition = i + 1;
108 }
109
110 return min;
111}
112
117{
118 unsigned long count = VuoListGetCount_VuoInteger(values);
119 if (count == 0)
120 {
121 *outputPosition = 0;
122 return 0;
123 }
124
125 VuoInteger *integers = VuoListGetData_VuoInteger(values);
126 VuoInteger max = LONG_MIN;
127 for (unsigned long i = 0; i < count; ++i)
128 if (integers[i] > max)
129 {
130 max = integers[i];
131 *outputPosition = i + 1;
132 }
133
134 return max;
135}
136
141{
143 if (count == 0)
144 return 0;
145
146 VuoInteger sum = 0;
147 for (VuoInteger i = 1; i <= count; ++i)
148 sum += VuoListGetValue_VuoInteger(values, i);
149
150 return sum/count;
151}
152
158{
159 VuoInteger rectifiedMin = (minimum < maximum) ? minimum : maximum;
160 VuoInteger rectifiedMax = (minimum < maximum) ? maximum : minimum;
161
162 if (value > rectifiedMax)
163 return rectifiedMin + ((value-rectifiedMax-1) % (rectifiedMax-rectifiedMin+1));
164 else if (value < rectifiedMin)
165 return rectifiedMax + ((value-rectifiedMin+1) % (rectifiedMax-rectifiedMin+1));
166 else
167 return value;
168}
169
194static u_int32_t VuoInteger_arc4random_uniform(u_int32_t upper_bound)
195{
196 u_int32_t r, min;
197
198 if (upper_bound < 2)
199 return 0;
200
201#if (ULONG_MAX > 0xffffffffUL)
202 min = 0x100000000UL % upper_bound;
203#else
204 /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
205 if (upper_bound > 0x80000000)
206 min = 1 + ~upper_bound; /* 2**32 - upper_bound */
207 else {
208 /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
209 min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
210 }
211#endif
212
213 /*
214 * This could theoretically loop forever but each retry has
215 * p > 0.5 (worst case, usually far better) of selecting a
216 * number inside the range we need, so it should rarely need
217 * to re-roll.
218 */
219 for (;;) {
220 r = arc4random();
221 if (r >= min)
222 break;
223 }
224
225 return r % upper_bound;
226}
227
236{
237 if (minimum == maximum)
238 return minimum;
239
240 VuoInteger actualMinimum = MIN(minimum,maximum);
241 VuoInteger actualMaximum = MAX(minimum,maximum);
242
243 return VuoInteger_arc4random_uniform(actualMaximum - actualMinimum + 1) + actualMinimum;
244}
245
249void VuoInteger_setRandomState(unsigned short state[3], const VuoInteger seed)
250{
251 state[0] = seed & 0xffff;
252 state[1] = (seed >> 16) & 0xffff;
253 state[2] = (seed >> 32) & 0xffff;
254}
255
267VuoInteger VuoInteger_randomWithState(unsigned short state[3], const VuoInteger minimum, const VuoInteger maximum)
268{
269 if (maximum < INT_MIN || maximum > INT_MAX || llabs(maximum - minimum) > INT_MAX)
270 return 0;
271
272 if (minimum == maximum)
273 return minimum;
274
275 VuoInteger actualMinimum = MIN(minimum,maximum);
276 VuoInteger actualMaximum = MAX(minimum,maximum);
277
278 // Based on https://www.mikeash.com/pyblog/friday-qa-2011-03-18-random-numbers.html
279 VuoInteger topPlusOne = actualMaximum - actualMinimum + 1;
280 VuoInteger two31 = 1U << 31;
281 VuoInteger maxUsable = (two31 / topPlusOne) * topPlusOne;
282
283 while (1)
284 {
285 VuoInteger num = jrand48(state);
286 if (num >= 0 && num < maxUsable)
287 return num % topPlusOne + actualMinimum;
288 }
289}
290
294static const char VuoInteger_hexToDec[256] =
295{
296 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
297 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
298 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
299 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
300 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0,
301 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
302 0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0,
303 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
304 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
305 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
306 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
307 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
308 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
309 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
310 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
311 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
312};
313
320{
321 return VuoInteger_hexToDec[byte];
322}
323
327bool VuoInteger_areEqual(const VuoInteger value1, const VuoInteger value2)
328{
329 return value1 == value2;
330}
331
336{
337 unsigned long count = VuoListGetCount_VuoInteger(values);
338 if (count <= 1)
339 return true;
340
341 VuoInteger *integers = VuoListGetData_VuoInteger(values);
342 VuoInteger min, max;
343 min = max = integers[0];
344 for (unsigned long i = 1; i < count; ++i)
345 {
346 min = MIN(min, integers[i]);
347 max = MAX(max, integers[i]);
348 }
349 return (max - min) <= tolerance;
350}
351
356{
357 return a < b;
358}
359
364{
365 return minimum <= value && value <= maximum;
366}