stb_divide.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. // stb_divide.h - v0.94 - public domain - Sean Barrett, Feb 2010
  2. // Three kinds of divide/modulus of signed integers.
  3. //
  4. // HISTORY
  5. //
  6. // v0.94 Fix integer overflow issues
  7. // v0.93 2020-02-02 Write useful exit() value from main()
  8. // v0.92 2019-02-25 Fix warning
  9. // v0.91 2010-02-27 Fix euclidean division by INT_MIN for non-truncating C
  10. // Check result with 64-bit math to catch such cases
  11. // v0.90 2010-02-24 First public release
  12. //
  13. // USAGE
  14. //
  15. // In *ONE* source file, put:
  16. //
  17. // #define STB_DIVIDE_IMPLEMENTATION
  18. // // #define C_INTEGER_DIVISION_TRUNCATES // see Note 1
  19. // // #define C_INTEGER_DIVISION_FLOORS // see Note 2
  20. // #include "stb_divide.h"
  21. //
  22. // Other source files should just include stb_divide.h
  23. //
  24. // Note 1: On platforms/compilers that you know signed C division
  25. // truncates, you can #define C_INTEGER_DIVISION_TRUNCATES.
  26. //
  27. // Note 2: On platforms/compilers that you know signed C division
  28. // floors (rounds to negative infinity), you can #define
  29. // C_INTEGER_DIVISION_FLOORS.
  30. //
  31. // You can #define STB_DIVIDE_TEST in which case the implementation
  32. // will generate a main() and compiling the result will create a
  33. // program that tests the implementation. Run it with no arguments
  34. // and any output indicates an error; run it with any argument and
  35. // it will also print the test results. Define STB_DIVIDE_TEST_64
  36. // to a 64-bit integer type to avoid overflows in the result-checking
  37. // which give false negatives.
  38. //
  39. // ABOUT
  40. //
  41. // This file provides three different consistent divide/mod pairs
  42. // implemented on top of arbitrary C/C++ division, including correct
  43. // handling of overflow of intermediate calculations:
  44. //
  45. // trunc: a/b truncates to 0, a%b has same sign as a
  46. // floor: a/b truncates to -inf, a%b has same sign as b
  47. // eucl: a/b truncates to sign(b)*inf, a%b is non-negative
  48. //
  49. // Not necessarily optimal; I tried to keep it generally efficient,
  50. // but there may be better ways.
  51. //
  52. // Briefly, for those who are not familiar with the problem, we note
  53. // the reason these divides exist and are interesting:
  54. //
  55. // 'trunc' is easy to implement in hardware (strip the signs,
  56. // compute, reapply the signs), thus is commonly defined
  57. // by many languages (including C99)
  58. //
  59. // 'floor' is simple to define and better behaved than trunc;
  60. // for example it divides integers into fixed-size buckets
  61. // without an extra-wide bucket at 0, and for a fixed
  62. // divisor N there are only |N| possible moduli.
  63. //
  64. // 'eucl' guarantees fixed-sized buckets *and* a non-negative
  65. // modulus and defines division to be whatever is needed
  66. // to achieve that result.
  67. //
  68. // See "The Euclidean definition of the functions div and mod"
  69. // by Raymond Boute (1992), or "Division and Modulus for Computer
  70. // Scientists" by Daan Leijen (2001)
  71. //
  72. // We assume of the built-in C division:
  73. // (a) modulus is the remainder for the corresponding division
  74. // (b) a/b truncates if a and b are the same sign
  75. //
  76. // Property (a) requires (a/b)*b + (a%b)==a, and is required by C.
  77. // Property (b) seems to be true of all hardware but is *not* satisfied
  78. // by the euclidean division operator we define, so it's possibly not
  79. // always true. If any such platform turns up, we can add more cases.
  80. // (Possibly only stb_div_trunc currently relies on property (b).)
  81. //
  82. // LICENSE
  83. //
  84. // See end of file for license information.
  85. #ifndef INCLUDE_STB_DIVIDE_H
  86. #define INCLUDE_STB_DIVIDE_H
  87. #ifdef __cplusplus
  88. extern "C" {
  89. #endif
  90. extern int stb_div_trunc(int value_to_be_divided, int value_to_divide_by);
  91. extern int stb_div_floor(int value_to_be_divided, int value_to_divide_by);
  92. extern int stb_div_eucl (int value_to_be_divided, int value_to_divide_by);
  93. extern int stb_mod_trunc(int value_to_be_divided, int value_to_divide_by);
  94. extern int stb_mod_floor(int value_to_be_divided, int value_to_divide_by);
  95. extern int stb_mod_eucl (int value_to_be_divided, int value_to_divide_by);
  96. #ifdef __cplusplus
  97. }
  98. #endif
  99. #ifdef STB_DIVIDE_IMPLEMENTATION
  100. #if defined(__STDC_VERSION) && __STDC_VERSION__ >= 19901
  101. #ifndef C_INTEGER_DIVISION_TRUNCATES
  102. #define C_INTEGER_DIVISION_TRUNCATES
  103. #endif
  104. #endif
  105. #ifndef INT_MIN
  106. #include <limits.h> // if you have no limits.h, #define INT_MIN yourself
  107. #endif
  108. // the following macros are designed to allow testing
  109. // other platforms by simulating them
  110. #ifndef STB_DIVIDE_TEST_FLOOR
  111. #define stb__div(a,b) ((a)/(b))
  112. #define stb__mod(a,b) ((a)%(b))
  113. #else
  114. // implement floor-style divide on trunc platform
  115. #ifndef C_INTEGER_DIVISION_TRUNCATES
  116. #error "floor test requires truncating division"
  117. #endif
  118. #undef C_INTEGER_DIVISION_TRUNCATES
  119. int stb__div(int v1, int v2)
  120. {
  121. int q = v1/v2, r = v1%v2;
  122. if ((r > 0 && v2 < 0) || (r < 0 && v2 > 0))
  123. return q-1;
  124. else
  125. return q;
  126. }
  127. int stb__mod(int v1, int v2)
  128. {
  129. int r = v1%v2;
  130. if ((r > 0 && v2 < 0) || (r < 0 && v2 > 0))
  131. return r+v2;
  132. else
  133. return r;
  134. }
  135. #endif
  136. int stb_div_trunc(int v1, int v2)
  137. {
  138. #ifdef C_INTEGER_DIVISION_TRUNCATES
  139. return v1/v2;
  140. #else
  141. if (v1 >= 0 && v2 <= 0)
  142. return -stb__div(-v1,v2); // both negative to avoid overflow
  143. if (v1 <= 0 && v2 >= 0)
  144. if (v1 != INT_MIN)
  145. return -stb__div(v1,-v2); // both negative to avoid overflow
  146. else
  147. return -stb__div(v1+v2,-v2)-1; // push v1 away from wrap point
  148. else
  149. return v1/v2; // same sign, so expect truncation
  150. #endif
  151. }
  152. int stb_div_floor(int v1, int v2)
  153. {
  154. #ifdef C_INTEGER_DIVISION_FLOORS
  155. return v1/v2;
  156. #else
  157. if (v1 >= 0 && v2 < 0) {
  158. if (v2 + 1 >= INT_MIN + v1) // check if increasing v1's magnitude overflows
  159. return -stb__div((v2+1)-v1,v2); // nope, so just compute it
  160. else
  161. return -stb__div(-v1,v2) + ((-v1)%v2 ? -1 : 0);
  162. }
  163. if (v1 < 0 && v2 >= 0) {
  164. if (v1 != INT_MIN) {
  165. if (v1 + 1 >= INT_MIN + v2) // check if increasing v1's magnitude overflows
  166. return -stb__div((v1+1)-v2,-v2); // nope, so just compute it
  167. else
  168. return -stb__div(-v1,v2) + (stb__mod(v1,-v2) ? -1 : 0);
  169. } else // it must be possible to compute -(v1+v2) without overflowing
  170. return -stb__div(-(v1+v2),v2) + (stb__mod(-(v1+v2),v2) ? -2 : -1);
  171. } else
  172. return v1/v2; // same sign, so expect truncation
  173. #endif
  174. }
  175. int stb_div_eucl(int v1, int v2)
  176. {
  177. int q,r;
  178. #ifdef C_INTEGER_DIVISION_TRUNCATES
  179. q = v1/v2;
  180. r = v1%v2;
  181. #else
  182. // handle every quadrant separately, since we can't rely on q and r flor
  183. if (v1 >= 0)
  184. if (v2 >= 0)
  185. return stb__div(v1,v2);
  186. else if (v2 != INT_MIN)
  187. q = -stb__div(v1,-v2), r = stb__mod(v1,-v2);
  188. else
  189. q = 0, r = v1;
  190. else if (v1 != INT_MIN)
  191. if (v2 >= 0)
  192. q = -stb__div(-v1,v2), r = -stb__mod(-v1,v2);
  193. else if (v2 != INT_MIN)
  194. q = stb__div(-v1,-v2), r = -stb__mod(-v1,-v2);
  195. else // if v2 is INT_MIN, then we can't use -v2, but we can't divide by v2
  196. q = 1, r = v1-q*v2;
  197. else // if v1 is INT_MIN, we have to move away from overflow place
  198. if (v2 >= 0)
  199. q = -stb__div(-(v1+v2),v2)-1, r = -stb__mod(-(v1+v2),v2);
  200. else if (v2 != INT_MIN)
  201. q = stb__div(-(v1-v2),-v2)+1, r = -stb__mod(-(v1-v2),-v2);
  202. else // for INT_MIN / INT_MIN, we need to be extra-careful to avoid overflow
  203. q = 1, r = 0;
  204. #endif
  205. if (r >= 0)
  206. return q;
  207. else
  208. return q + (v2 > 0 ? -1 : 1);
  209. }
  210. int stb_mod_trunc(int v1, int v2)
  211. {
  212. #ifdef C_INTEGER_DIVISION_TRUNCATES
  213. return v1%v2;
  214. #else
  215. if (v1 >= 0) { // modulus result should always be positive
  216. int r = stb__mod(v1,v2);
  217. if (r >= 0)
  218. return r;
  219. else
  220. return r - (v2 < 0 ? v2 : -v2);
  221. } else { // modulus result should always be negative
  222. int r = stb__mod(v1,v2);
  223. if (r <= 0)
  224. return r;
  225. else
  226. return r + (v2 < 0 ? v2 : -v2);
  227. }
  228. #endif
  229. }
  230. int stb_mod_floor(int v1, int v2)
  231. {
  232. #ifdef C_INTEGER_DIVISION_FLOORS
  233. return v1%v2;
  234. #else
  235. if (v2 >= 0) { // result should always be positive
  236. int r = stb__mod(v1,v2);
  237. if (r >= 0)
  238. return r;
  239. else
  240. return r + v2;
  241. } else { // result should always be negative
  242. int r = stb__mod(v1,v2);
  243. if (r <= 0)
  244. return r;
  245. else
  246. return r + v2;
  247. }
  248. #endif
  249. }
  250. int stb_mod_eucl(int v1, int v2)
  251. {
  252. int r = stb__mod(v1,v2);
  253. if (r >= 0)
  254. return r;
  255. else
  256. return r - (v2 < 0 ? v2 : -v2); // negative abs() [to avoid overflow]
  257. }
  258. #ifdef STB_DIVIDE_TEST
  259. #include <stdio.h>
  260. #include <math.h>
  261. #include <limits.h>
  262. int show=0;
  263. int err=0;
  264. void stbdiv_check(int q, int r, int a, int b, char *type, int dir)
  265. {
  266. if ((dir > 0 && r < 0) || (dir < 0 && r > 0)) {
  267. fprintf(stderr, "FAILED: %s(%d,%d) remainder %d in wrong direction\n", type,a,b,r);
  268. err++;
  269. } else
  270. if (b != INT_MIN) // can't compute abs(), but if b==INT_MIN all remainders are valid
  271. if (r <= -abs(b) || r >= abs(b)) {
  272. fprintf(stderr, "FAILED: %s(%d,%d) remainder %d out of range\n", type,a,b,r);
  273. err++;
  274. }
  275. #ifdef STB_DIVIDE_TEST_64
  276. {
  277. STB_DIVIDE_TEST_64 q64 = q, r64=r, a64=a, b64=b;
  278. if (q64*b64+r64 != a64) {
  279. fprintf(stderr, "FAILED: %s(%d,%d) remainder %d doesn't match quotient %d\n", type,a,b,r,q);
  280. err++;
  281. }
  282. }
  283. #else
  284. if (q*b+r != a) {
  285. fprintf(stderr, "FAILED: %s(%d,%d) remainder %d doesn't match quotient %d\n", type,a,b,r,q);
  286. err++;
  287. }
  288. #endif
  289. }
  290. void test(int a, int b)
  291. {
  292. int q,r;
  293. if (show) printf("(%+11d,%+d) | ", a,b);
  294. q = stb_div_trunc(a,b), r = stb_mod_trunc(a,b);
  295. if (show) printf("(%+11d,%+2d) ", q,r); stbdiv_check(q,r,a,b, "trunc",a);
  296. q = stb_div_floor(a,b), r = stb_mod_floor(a,b);
  297. if (show) printf("(%+11d,%+2d) ", q,r); stbdiv_check(q,r,a,b, "floor",b);
  298. q = stb_div_eucl (a,b), r = stb_mod_eucl (a,b);
  299. if (show) printf("(%+11d,%+2d)\n", q,r); stbdiv_check(q,r,a,b, "euclidean",1);
  300. }
  301. void testh(int a, int b)
  302. {
  303. int q,r;
  304. if (show) printf("(%08x,%08x) |\n", a,b);
  305. q = stb_div_trunc(a,b), r = stb_mod_trunc(a,b); stbdiv_check(q,r,a,b, "trunc",a);
  306. if (show) printf(" (%08x,%08x)", q,r);
  307. q = stb_div_floor(a,b), r = stb_mod_floor(a,b); stbdiv_check(q,r,a,b, "floor",b);
  308. if (show) printf(" (%08x,%08x)", q,r);
  309. q = stb_div_eucl (a,b), r = stb_mod_eucl (a,b); stbdiv_check(q,r,a,b, "euclidean",1);
  310. if (show) printf(" (%08x,%08x)\n ", q,r);
  311. }
  312. int main(int argc, char **argv)
  313. {
  314. if (argc > 1) show=1;
  315. test(8,3);
  316. test(8,-3);
  317. test(-8,3);
  318. test(-8,-3);
  319. test(1,2);
  320. test(1,-2);
  321. test(-1,2);
  322. test(-1,-2);
  323. test(8,4);
  324. test(8,-4);
  325. test(-8,4);
  326. test(-8,-4);
  327. test(INT_MAX,1);
  328. test(INT_MIN,1);
  329. test(INT_MIN+1,1);
  330. test(INT_MAX,-1);
  331. //test(INT_MIN,-1); // this traps in MSVC, so we leave it untested
  332. test(INT_MIN+1,-1);
  333. test(INT_MIN,-2);
  334. test(INT_MIN+1,2);
  335. test(INT_MIN+1,-2);
  336. test(INT_MAX,2);
  337. test(INT_MAX,-2);
  338. test(INT_MIN+1,2);
  339. test(INT_MIN+1,-2);
  340. test(INT_MIN,2);
  341. test(INT_MIN,-2);
  342. test(INT_MIN,7);
  343. test(INT_MIN,-7);
  344. test(INT_MIN+1,4);
  345. test(INT_MIN+1,-4);
  346. testh(-7, INT_MIN);
  347. testh(-1, INT_MIN);
  348. testh(1, INT_MIN);
  349. testh(7, INT_MIN);
  350. testh(INT_MAX-1, INT_MIN);
  351. testh(INT_MAX, INT_MIN);
  352. testh(INT_MIN, INT_MIN);
  353. testh(INT_MIN+1, INT_MIN);
  354. testh(INT_MAX-1, INT_MAX);
  355. testh(INT_MAX , INT_MAX);
  356. testh(INT_MIN , INT_MAX);
  357. testh(INT_MIN+1, INT_MAX);
  358. return err > 0 ? 1 : 0;
  359. }
  360. #endif // STB_DIVIDE_TEST
  361. #endif // STB_DIVIDE_IMPLEMENTATION
  362. #endif // INCLUDE_STB_DIVIDE_H
  363. /*
  364. ------------------------------------------------------------------------------
  365. This software is available under 2 licenses -- choose whichever you prefer.
  366. ------------------------------------------------------------------------------
  367. ALTERNATIVE A - MIT License
  368. Copyright (c) 2017 Sean Barrett
  369. Permission is hereby granted, free of charge, to any person obtaining a copy of
  370. this software and associated documentation files (the "Software"), to deal in
  371. the Software without restriction, including without limitation the rights to
  372. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  373. of the Software, and to permit persons to whom the Software is furnished to do
  374. so, subject to the following conditions:
  375. The above copyright notice and this permission notice shall be included in all
  376. copies or substantial portions of the Software.
  377. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  378. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  379. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  380. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  381. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  382. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  383. SOFTWARE.
  384. ------------------------------------------------------------------------------
  385. ALTERNATIVE B - Public Domain (www.unlicense.org)
  386. This is free and unencumbered software released into the public domain.
  387. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
  388. software, either in source code form or as a compiled binary, for any purpose,
  389. commercial or non-commercial, and by any means.
  390. In jurisdictions that recognize copyright laws, the author or authors of this
  391. software dedicate any and all copyright interest in the software to the public
  392. domain. We make this dedication for the benefit of the public at large and to
  393. the detriment of our heirs and successors. We intend this dedication to be an
  394. overt act of relinquishment in perpetuity of all present and future rights to
  395. this software under copyright law.
  396. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  397. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  398. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  399. AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  400. ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  401. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  402. ------------------------------------------------------------------------------
  403. */