Vuo  2.1.2
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
26 
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
41  {
42  // Use strtold() instead of json_object_get_int64(),
43  // since the latter doesn't support JSON strings with scientific notation.
44  // Use `long double strtold()` instead of `double atof()`
45  // since `long double` can precisely represent the int64 max value, whereas `double` can't.
46  const char *s = json_object_get_string(js);
47  if (s)
48  return strtold(s, NULL);
49  else
50  return 0;
51  }
52 }
53 
59 {
60  return json_object_new_int64(value);
61 }
62 
67 char * VuoInteger_getSummary(const VuoInteger value)
68 {
69  json_object *js = VuoInteger_getJson(value);
70  char *summary = strdup(json_object_to_json_string_ext(js,JSON_C_TO_STRING_PLAIN));
71  json_object_put(js);
72  return summary;
73 }
74 
79 {
80  unsigned long count = VuoListGetCount_VuoInteger(values);
81  if (count == 0)
82  {
83  *outputPosition = 0;
84  return 0;
85  }
86 
87  VuoInteger *integers = VuoListGetData_VuoInteger(values);
88  VuoInteger min = LONG_MAX;
89  for (unsigned long i = 0; i < count; ++i)
90  if (integers[i] < min)
91  {
92  min = integers[i];
93  *outputPosition = i + 1;
94  }
95 
96  return min;
97 }
98 
103 {
104  unsigned long count = VuoListGetCount_VuoInteger(values);
105  if (count == 0)
106  {
107  *outputPosition = 0;
108  return 0;
109  }
110 
111  VuoInteger *integers = VuoListGetData_VuoInteger(values);
112  VuoInteger max = LONG_MIN;
113  for (unsigned long i = 0; i < count; ++i)
114  if (integers[i] > max)
115  {
116  max = integers[i];
117  *outputPosition = i + 1;
118  }
119 
120  return max;
121 }
122 
127 {
128  VuoInteger count = VuoListGetCount_VuoInteger(values);
129  if (count == 0)
130  return 0;
131 
132  VuoInteger sum = 0;
133  for (VuoInteger i = 1; i <= count; ++i)
134  sum += VuoListGetValue_VuoInteger(values, i);
135 
136  return sum/count;
137 }
138 
144 {
145  VuoInteger rectifiedMin = (minimum < maximum) ? minimum : maximum;
146  VuoInteger rectifiedMax = (minimum < maximum) ? maximum : minimum;
147 
148  if (value > rectifiedMax)
149  return rectifiedMin + ((value-rectifiedMax-1) % (rectifiedMax-rectifiedMin+1));
150  else if (value < rectifiedMin)
151  return rectifiedMax + ((value-rectifiedMin+1) % (rectifiedMax-rectifiedMin+1));
152  else
153  return value;
154 }
155 
180 static u_int32_t VuoInteger_arc4random_uniform(u_int32_t upper_bound)
181 {
182  u_int32_t r, min;
183 
184  if (upper_bound < 2)
185  return 0;
186 
187 #if (ULONG_MAX > 0xffffffffUL)
188  min = 0x100000000UL % upper_bound;
189 #else
190  /* Calculate (2**32 % upper_bound) avoiding 64-bit math */
191  if (upper_bound > 0x80000000)
192  min = 1 + ~upper_bound; /* 2**32 - upper_bound */
193  else {
194  /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */
195  min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound;
196  }
197 #endif
198 
199  /*
200  * This could theoretically loop forever but each retry has
201  * p > 0.5 (worst case, usually far better) of selecting a
202  * number inside the range we need, so it should rarely need
203  * to re-roll.
204  */
205  for (;;) {
206  r = arc4random();
207  if (r >= min)
208  break;
209  }
210 
211  return r % upper_bound;
212 }
213 
221 VuoInteger VuoInteger_random(const VuoInteger minimum, const VuoInteger maximum)
222 {
223  if (minimum == maximum)
224  return minimum;
225 
226  VuoInteger actualMinimum = MIN(minimum,maximum);
227  VuoInteger actualMaximum = MAX(minimum,maximum);
228 
229  return VuoInteger_arc4random_uniform(actualMaximum - actualMinimum + 1) + actualMinimum;
230 }
231 
235 void VuoInteger_setRandomState(unsigned short state[3], const VuoInteger seed)
236 {
237  state[0] = seed & 0xffff;
238  state[1] = (seed >> 16) & 0xffff;
239  state[2] = (seed >> 32) & 0xffff;
240 }
241 
252 VuoInteger VuoInteger_randomWithState(unsigned short state[3], const VuoInteger minimum, const VuoInteger maximum)
253 {
254  if (minimum == maximum)
255  return minimum;
256 
257  VuoInteger actualMinimum = MIN(minimum,maximum);
258  VuoInteger actualMaximum = MAX(minimum,maximum);
259 
260  // Based on https://www.mikeash.com/pyblog/friday-qa-2011-03-18-random-numbers.html
261  VuoInteger topPlusOne = actualMaximum - actualMinimum + 1;
262  VuoInteger two31 = 1U << 31;
263  VuoInteger maxUsable = (two31 / topPlusOne) * topPlusOne;
264 
265  while (1)
266  {
267  VuoInteger num = jrand48(state);
268  if (num >= 0 && num < maxUsable)
269  return num % topPlusOne + actualMinimum;
270  }
271 }
272 
276 static const char VuoInteger_hexToDec[256] =
277 {
278  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
279  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
280  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
281  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0,
282  0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0,
283  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
284  0, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 0, 0, 0, 0, 0, 0, 0, 0,
285  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
286  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
287  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
288  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
289  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
290  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
291  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
292  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
293  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
294 };
295 
302 {
303  return VuoInteger_hexToDec[byte];
304 }
305 
309 bool VuoInteger_areEqual(const VuoInteger value1, const VuoInteger value2)
310 {
311  return value1 == value2;
312 }
313 
318 {
319  unsigned long count = VuoListGetCount_VuoInteger(values);
320  if (count <= 1)
321  return true;
322 
323  VuoInteger *integers = VuoListGetData_VuoInteger(values);
324  VuoInteger min, max;
325  min = max = integers[0];
326  for (unsigned long i = 1; i < count; ++i)
327  {
328  min = MIN(min, integers[i]);
329  max = MAX(max, integers[i]);
330  }
331  return (max - min) <= tolerance;
332 }
333 
338 {
339  return a < b;
340 }
341 
346 {
347  return minimum <= value && value <= maximum;
348 }