_soft_numbers.odin 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #shared_global_scope;
  2. // import "fmt.odin";
  3. // proc __u128_mod(a, b: u128) -> u128 #link_name "__umodti3" {
  4. // var _, r := __u128_quo_mod(a, b)
  5. // return r
  6. // }
  7. // proc __u128_quo(a, b: u128) -> u128 #link_name "__udivti3" {
  8. // var n, _ := __u128_quo_mod(a, b)
  9. // return n
  10. // }
  11. // proc __i128_mod(a, b: i128) -> i128 #link_name "__modti3" {
  12. // var _, r := __i128_quo_mod(a, b)
  13. // return r
  14. // }
  15. // proc __i128_quo(a, b: i128) -> i128 #link_name "__divti3" {
  16. // var n, _ := __i128_quo_mod(a, b)
  17. // return n
  18. // }
  19. // proc __i128_quo_mod(a, b: i128) -> (i128, i128) #link_name "__divmodti4" {
  20. // var s := b >> 127
  21. // b = (b ~ s) - s
  22. // s = a >> 127
  23. // a = (a ~ s) - s
  24. // var n, r := __u128_quo_mod(a as u128, b as u128)
  25. // return (n as i128 ~ s) - s, (r as i128 ~ s) - s
  26. // }
  27. // proc __u128_quo_mod(a, b: u128) -> (u128, u128) #link_name "__udivmodti4" {
  28. // proc clz(x: u64) -> u64 {
  29. // proc clz_u64(x: u64, is_zero_undef: bool) -> u64 #foreign "llvm.ctlz.i64"
  30. // return clz_u64(x, false)
  31. // }
  32. // proc ctz(x: u64) -> u64 {
  33. // proc ctz_u64(x: u64, is_zero_undef: bool) -> u64 #foreign "llvm.cttz.i64"
  34. // return ctz_u64(x, false)
  35. // }
  36. // u128_lo_hi :: raw_union {
  37. // all: u128
  38. // using _lohi: struct {lo, hi: u64;}
  39. // }
  40. // n, d, q, r: u128_lo_hi
  41. // sr: u64
  42. // n.all = a
  43. // d.all = b
  44. // if n.hi == 0 {
  45. // if d.hi == 0 {
  46. // return (n.lo / d.lo) as u128, (n.lo % d.lo) as u128
  47. // }
  48. // return 0, n.lo as u128
  49. // }
  50. // if d.lo == 0 {
  51. // if d.hi == 0 {
  52. // return (n.hi / d.lo) as u128, (n.hi % d.lo) as u128
  53. // }
  54. // if n.lo == 0 {
  55. // r.hi = n.hi % d.hi
  56. // r.lo = 0
  57. // return (n.hi / d.hi) as u128, r.all
  58. // }
  59. // if (d.hi & (d.hi-1)) == 0 {
  60. // r.lo = n.lo
  61. // r.hi = n.hi & (d.hi-1)
  62. // return (n.hi >> ctz(d.hi)) as u128, r.all
  63. // }
  64. // sr = clz(d.hi) - clz(n.hi)
  65. // if sr > 64 - 2 {
  66. // return 0, n.all
  67. // }
  68. // sr++
  69. // q.lo = 0
  70. // q.hi = n.lo << (64-sr)
  71. // r.hi = n.hi >> sr
  72. // r.lo = (n.hi << (64-sr)) | (n.lo >> sr)
  73. // } else {
  74. // if d.hi == 0 {
  75. // if (d.lo & (d.lo - 1)) == 0 {
  76. // var rem := (n.lo % (d.lo - 1)) as u128
  77. // if d.lo == 1 {
  78. // return n.all, rem
  79. // }
  80. // sr = ctz(d.lo)
  81. // q.hi = n.hi >> sr
  82. // q.lo = (n.hi << (64-sr)) | (n.lo >> sr)
  83. // return q.all, rem
  84. // }
  85. // sr = 1 + 64 + clz(d.lo) - clz(n.hi)
  86. // q.all = n.all << (128-sr)
  87. // r.all = n.all >> sr
  88. // if sr == 64 {
  89. // q.lo = 0
  90. // q.hi = n.lo
  91. // r.hi = 0
  92. // r.lo = n.hi
  93. // } else if sr < 64 {
  94. // q.lo = 0
  95. // q.hi = n.lo << (64-sr)
  96. // r.hi = n.hi >> sr
  97. // r.lo = (n.hi << (64-sr)) | (n.lo >> sr)
  98. // } else {
  99. // q.lo = n.lo << (128-sr)
  100. // q.hi = (n.hi << (128-sr)) | (n.lo >> (sr-64))
  101. // r.hi = 0
  102. // r.lo = n.hi >> (sr-64)
  103. // }
  104. // } else {
  105. // sr = clz(d.hi) - clz(n.hi)
  106. // if sr > 64-1 {
  107. // return 0, n.all
  108. // }
  109. // sr++
  110. // q.lo = 0
  111. // q.hi = n.lo << (64-sr)
  112. // r.all = n.all >> sr
  113. // if sr < 64 {
  114. // r.hi = n.hi >> sr
  115. // r.lo = (n.hi << (64-sr)) | (n.lo >> sr)
  116. // } else {
  117. // r.hi = 0
  118. // r.lo = n.hi
  119. // }
  120. // }
  121. // }
  122. // carry: u64
  123. // for ; sr > 0; sr-- {
  124. // r.hi = (r.hi << 1) | (r.lo >> (64-1))
  125. // r.lo = (r.lo << 1) | (r.hi >> (64-1))
  126. // q.hi = (q.hi << 1) | (q.lo >> (64-1))
  127. // q.lo = (q.lo << 1) | carry
  128. // carry = 0
  129. // if r.all >= d.all {
  130. // r.all -= d.all
  131. // carry = 1
  132. // }
  133. // }
  134. // q.all = (q.all << 1) | (carry as u128)
  135. // return q.all, r.all
  136. // }