int128.h 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #ifndef INT128_H
  2. #define INT128_H
  3. typedef struct Int128 Int128;
  4. struct Int128 {
  5. uint64_t lo;
  6. int64_t hi;
  7. };
  8. static inline Int128 int128_make64(uint64_t a)
  9. {
  10. return (Int128) { a, 0 };
  11. }
  12. static inline uint64_t int128_get64(Int128 a)
  13. {
  14. assert(!a.hi);
  15. return a.lo;
  16. }
  17. static inline Int128 int128_zero(void)
  18. {
  19. return int128_make64(0);
  20. }
  21. static inline Int128 int128_one(void)
  22. {
  23. return int128_make64(1);
  24. }
  25. static inline Int128 int128_2_64(void)
  26. {
  27. return (Int128) { 0, 1 };
  28. }
  29. static inline Int128 int128_add(Int128 a, Int128 b)
  30. {
  31. Int128 r = { a.lo + b.lo, a.hi + b.hi };
  32. r.hi += (r.lo < a.lo) || (r.lo < b.lo);
  33. return r;
  34. }
  35. static inline Int128 int128_neg(Int128 a)
  36. {
  37. a.lo = ~a.lo;
  38. a.hi = ~a.hi;
  39. return int128_add(a, int128_one());
  40. }
  41. static inline Int128 int128_sub(Int128 a, Int128 b)
  42. {
  43. return int128_add(a, int128_neg(b));
  44. }
  45. static inline bool int128_nonneg(Int128 a)
  46. {
  47. return a.hi >= 0;
  48. }
  49. static inline bool int128_eq(Int128 a, Int128 b)
  50. {
  51. return a.lo == b.lo && a.hi == b.hi;
  52. }
  53. static inline bool int128_ne(Int128 a, Int128 b)
  54. {
  55. return !int128_eq(a, b);
  56. }
  57. static inline bool int128_ge(Int128 a, Int128 b)
  58. {
  59. return int128_nonneg(int128_sub(a, b));
  60. }
  61. static inline bool int128_lt(Int128 a, Int128 b)
  62. {
  63. return !int128_ge(a, b);
  64. }
  65. static inline bool int128_le(Int128 a, Int128 b)
  66. {
  67. return int128_ge(b, a);
  68. }
  69. static inline bool int128_gt(Int128 a, Int128 b)
  70. {
  71. return !int128_le(a, b);
  72. }
  73. static inline bool int128_nz(Int128 a)
  74. {
  75. return a.lo || a.hi;
  76. }
  77. static inline Int128 int128_min(Int128 a, Int128 b)
  78. {
  79. return int128_le(a, b) ? a : b;
  80. }
  81. static inline Int128 int128_max(Int128 a, Int128 b)
  82. {
  83. return int128_ge(a, b) ? a : b;
  84. }
  85. static inline void int128_addto(Int128 *a, Int128 b)
  86. {
  87. *a = int128_add(*a, b);
  88. }
  89. static inline void int128_subfrom(Int128 *a, Int128 b)
  90. {
  91. *a = int128_sub(*a, b);
  92. }
  93. #endif