arithmetics.nim 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. proc succ*[T: Ordinal](x: T, y: int = 1): T {.magic: "Succ", noSideEffect.} =
  2. ## Returns the `y`-th successor (default: 1) of the value `x`.
  3. ##
  4. ## If such a value does not exist, `OverflowDefect` is raised
  5. ## or a compile time error occurs.
  6. runnableExamples:
  7. assert succ(5) == 6
  8. assert succ(5, 3) == 8
  9. proc pred*[T: Ordinal](x: T, y: int = 1): T {.magic: "Pred", noSideEffect.} =
  10. ## Returns the `y`-th predecessor (default: 1) of the value `x`.
  11. ##
  12. ## If such a value does not exist, `OverflowDefect` is raised
  13. ## or a compile time error occurs.
  14. runnableExamples:
  15. assert pred(5) == 4
  16. assert pred(5, 3) == 2
  17. proc inc*[T: Ordinal](x: var T, y: int = 1) {.magic: "Inc", noSideEffect.} =
  18. ## Increments the ordinal `x` by `y`.
  19. ##
  20. ## If such a value does not exist, `OverflowDefect` is raised or a compile
  21. ## time error occurs. This is a short notation for: `x = succ(x, y)`.
  22. runnableExamples:
  23. var i = 2
  24. inc(i)
  25. assert i == 3
  26. inc(i, 3)
  27. assert i == 6
  28. proc dec*[T: Ordinal](x: var T, y: int = 1) {.magic: "Dec", noSideEffect.} =
  29. ## Decrements the ordinal `x` by `y`.
  30. ##
  31. ## If such a value does not exist, `OverflowDefect` is raised or a compile
  32. ## time error occurs. This is a short notation for: `x = pred(x, y)`.
  33. runnableExamples:
  34. var i = 2
  35. dec(i)
  36. assert i == 1
  37. dec(i, 3)
  38. assert i == -2
  39. # --------------------------------------------------------------------------
  40. # built-in operators
  41. # integer calculations:
  42. proc `+`*(x: int): int {.magic: "UnaryPlusI", noSideEffect.}
  43. ## Unary `+` operator for an integer. Has no effect.
  44. proc `+`*(x: int8): int8 {.magic: "UnaryPlusI", noSideEffect.}
  45. proc `+`*(x: int16): int16 {.magic: "UnaryPlusI", noSideEffect.}
  46. proc `+`*(x: int32): int32 {.magic: "UnaryPlusI", noSideEffect.}
  47. proc `+`*(x: int64): int64 {.magic: "UnaryPlusI", noSideEffect.}
  48. proc `-`*(x: int): int {.magic: "UnaryMinusI", noSideEffect.}
  49. ## Unary `-` operator for an integer. Negates `x`.
  50. proc `-`*(x: int8): int8 {.magic: "UnaryMinusI", noSideEffect.}
  51. proc `-`*(x: int16): int16 {.magic: "UnaryMinusI", noSideEffect.}
  52. proc `-`*(x: int32): int32 {.magic: "UnaryMinusI", noSideEffect.}
  53. proc `-`*(x: int64): int64 {.magic: "UnaryMinusI64", noSideEffect.}
  54. proc `not`*(x: int): int {.magic: "BitnotI", noSideEffect.} =
  55. ## Computes the `bitwise complement` of the integer `x`.
  56. runnableExamples:
  57. assert not 0'u8 == 255
  58. assert not 0'i8 == -1
  59. assert not 1000'u16 == 64535
  60. assert not 1000'i16 == -1001
  61. proc `not`*(x: int8): int8 {.magic: "BitnotI", noSideEffect.}
  62. proc `not`*(x: int16): int16 {.magic: "BitnotI", noSideEffect.}
  63. proc `not`*(x: int32): int32 {.magic: "BitnotI", noSideEffect.}
  64. proc `not`*(x: int64): int64 {.magic: "BitnotI", noSideEffect.}
  65. proc `+`*(x, y: int): int {.magic: "AddI", noSideEffect.}
  66. ## Binary `+` operator for an integer.
  67. proc `+`*(x, y: int8): int8 {.magic: "AddI", noSideEffect.}
  68. proc `+`*(x, y: int16): int16 {.magic: "AddI", noSideEffect.}
  69. proc `+`*(x, y: int32): int32 {.magic: "AddI", noSideEffect.}
  70. proc `+`*(x, y: int64): int64 {.magic: "AddI", noSideEffect.}
  71. proc `-`*(x, y: int): int {.magic: "SubI", noSideEffect.}
  72. ## Binary `-` operator for an integer.
  73. proc `-`*(x, y: int8): int8 {.magic: "SubI", noSideEffect.}
  74. proc `-`*(x, y: int16): int16 {.magic: "SubI", noSideEffect.}
  75. proc `-`*(x, y: int32): int32 {.magic: "SubI", noSideEffect.}
  76. proc `-`*(x, y: int64): int64 {.magic: "SubI", noSideEffect.}
  77. proc `*`*(x, y: int): int {.magic: "MulI", noSideEffect.}
  78. ## Binary `*` operator for an integer.
  79. proc `*`*(x, y: int8): int8 {.magic: "MulI", noSideEffect.}
  80. proc `*`*(x, y: int16): int16 {.magic: "MulI", noSideEffect.}
  81. proc `*`*(x, y: int32): int32 {.magic: "MulI", noSideEffect.}
  82. proc `*`*(x, y: int64): int64 {.magic: "MulI", noSideEffect.}
  83. proc `div`*(x, y: int): int {.magic: "DivI", noSideEffect.} =
  84. ## Computes the integer division.
  85. ##
  86. ## This is roughly the same as `math.trunc(x/y).int`.
  87. runnableExamples:
  88. assert (1 div 2) == 0
  89. assert (2 div 2) == 1
  90. assert (3 div 2) == 1
  91. assert (7 div 3) == 2
  92. assert (-7 div 3) == -2
  93. assert (7 div -3) == -2
  94. assert (-7 div -3) == 2
  95. proc `div`*(x, y: int8): int8 {.magic: "DivI", noSideEffect.}
  96. proc `div`*(x, y: int16): int16 {.magic: "DivI", noSideEffect.}
  97. proc `div`*(x, y: int32): int32 {.magic: "DivI", noSideEffect.}
  98. proc `div`*(x, y: int64): int64 {.magic: "DivI", noSideEffect.}
  99. proc `mod`*(x, y: int): int {.magic: "ModI", noSideEffect.} =
  100. ## Computes the integer modulo operation (remainder).
  101. ##
  102. ## This is the same as `x - (x div y) * y`.
  103. runnableExamples:
  104. assert (7 mod 5) == 2
  105. assert (-7 mod 5) == -2
  106. assert (7 mod -5) == 2
  107. assert (-7 mod -5) == -2
  108. proc `mod`*(x, y: int8): int8 {.magic: "ModI", noSideEffect.}
  109. proc `mod`*(x, y: int16): int16 {.magic: "ModI", noSideEffect.}
  110. proc `mod`*(x, y: int32): int32 {.magic: "ModI", noSideEffect.}
  111. proc `mod`*(x, y: int64): int64 {.magic: "ModI", noSideEffect.}
  112. when defined(nimOldShiftRight):
  113. const shrDepMessage = "`shr` will become sign preserving."
  114. proc `shr`*(x: int, y: SomeInteger): int {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
  115. proc `shr`*(x: int8, y: SomeInteger): int8 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
  116. proc `shr`*(x: int16, y: SomeInteger): int16 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
  117. proc `shr`*(x: int32, y: SomeInteger): int32 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
  118. proc `shr`*(x: int64, y: SomeInteger): int64 {.magic: "ShrI", noSideEffect, deprecated: shrDepMessage.}
  119. else:
  120. proc `shr`*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
  121. ## Computes the `shift right` operation of `x` and `y`, filling
  122. ## vacant bit positions with the sign bit.
  123. ##
  124. ## **Note**: `Operator precedence <manual.html#syntax-precedence>`_
  125. ## is different than in *C*.
  126. ##
  127. ## See also:
  128. ## * `ashr func<#ashr,int,SomeInteger>`_ for arithmetic shift right
  129. runnableExamples:
  130. assert 0b0001_0000'i8 shr 2 == 0b0000_0100'i8
  131. assert 0b0000_0001'i8 shr 1 == 0b0000_0000'i8
  132. assert 0b1000_0000'i8 shr 4 == 0b1111_1000'i8
  133. assert -1 shr 5 == -1
  134. assert 1 shr 5 == 0
  135. assert 16 shr 2 == 4
  136. assert -16 shr 2 == -4
  137. proc `shr`*(x: int8, y: SomeInteger): int8 {.magic: "AshrI", noSideEffect.}
  138. proc `shr`*(x: int16, y: SomeInteger): int16 {.magic: "AshrI", noSideEffect.}
  139. proc `shr`*(x: int32, y: SomeInteger): int32 {.magic: "AshrI", noSideEffect.}
  140. proc `shr`*(x: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
  141. proc `shl`*(x: int, y: SomeInteger): int {.magic: "ShlI", noSideEffect.} =
  142. ## Computes the `shift left` operation of `x` and `y`.
  143. ##
  144. ## **Note**: `Operator precedence <manual.html#syntax-precedence>`_
  145. ## is different than in *C*.
  146. runnableExamples:
  147. assert 1'i32 shl 4 == 0x0000_0010
  148. assert 1'i64 shl 4 == 0x0000_0000_0000_0010
  149. proc `shl`*(x: int8, y: SomeInteger): int8 {.magic: "ShlI", noSideEffect.}
  150. proc `shl`*(x: int16, y: SomeInteger): int16 {.magic: "ShlI", noSideEffect.}
  151. proc `shl`*(x: int32, y: SomeInteger): int32 {.magic: "ShlI", noSideEffect.}
  152. proc `shl`*(x: int64, y: SomeInteger): int64 {.magic: "ShlI", noSideEffect.}
  153. proc ashr*(x: int, y: SomeInteger): int {.magic: "AshrI", noSideEffect.} =
  154. ## Shifts right by pushing copies of the leftmost bit in from the left,
  155. ## and let the rightmost bits fall off.
  156. ##
  157. ## Note that `ashr` is not an operator so use the normal function
  158. ## call syntax for it.
  159. ##
  160. ## See also:
  161. ## * `shr func<#shr,int,SomeInteger>`_
  162. runnableExamples:
  163. assert ashr(0b0001_0000'i8, 2) == 0b0000_0100'i8
  164. assert ashr(0b1000_0000'i8, 8) == 0b1111_1111'i8
  165. assert ashr(0b1000_0000'i8, 1) == 0b1100_0000'i8
  166. proc ashr*(x: int8, y: SomeInteger): int8 {.magic: "AshrI", noSideEffect.}
  167. proc ashr*(x: int16, y: SomeInteger): int16 {.magic: "AshrI", noSideEffect.}
  168. proc ashr*(x: int32, y: SomeInteger): int32 {.magic: "AshrI", noSideEffect.}
  169. proc ashr*(x: int64, y: SomeInteger): int64 {.magic: "AshrI", noSideEffect.}
  170. proc `and`*(x, y: int): int {.magic: "BitandI", noSideEffect.} =
  171. ## Computes the `bitwise and` of numbers `x` and `y`.
  172. runnableExamples:
  173. assert (0b0011 and 0b0101) == 0b0001
  174. assert (0b0111 and 0b1100) == 0b0100
  175. proc `and`*(x, y: int8): int8 {.magic: "BitandI", noSideEffect.}
  176. proc `and`*(x, y: int16): int16 {.magic: "BitandI", noSideEffect.}
  177. proc `and`*(x, y: int32): int32 {.magic: "BitandI", noSideEffect.}
  178. proc `and`*(x, y: int64): int64 {.magic: "BitandI", noSideEffect.}
  179. proc `or`*(x, y: int): int {.magic: "BitorI", noSideEffect.} =
  180. ## Computes the `bitwise or` of numbers `x` and `y`.
  181. runnableExamples:
  182. assert (0b0011 or 0b0101) == 0b0111
  183. assert (0b0111 or 0b1100) == 0b1111
  184. proc `or`*(x, y: int8): int8 {.magic: "BitorI", noSideEffect.}
  185. proc `or`*(x, y: int16): int16 {.magic: "BitorI", noSideEffect.}
  186. proc `or`*(x, y: int32): int32 {.magic: "BitorI", noSideEffect.}
  187. proc `or`*(x, y: int64): int64 {.magic: "BitorI", noSideEffect.}
  188. proc `xor`*(x, y: int): int {.magic: "BitxorI", noSideEffect.} =
  189. ## Computes the `bitwise xor` of numbers `x` and `y`.
  190. runnableExamples:
  191. assert (0b0011 xor 0b0101) == 0b0110
  192. assert (0b0111 xor 0b1100) == 0b1011
  193. proc `xor`*(x, y: int8): int8 {.magic: "BitxorI", noSideEffect.}
  194. proc `xor`*(x, y: int16): int16 {.magic: "BitxorI", noSideEffect.}
  195. proc `xor`*(x, y: int32): int32 {.magic: "BitxorI", noSideEffect.}
  196. proc `xor`*(x, y: int64): int64 {.magic: "BitxorI", noSideEffect.}
  197. # unsigned integer operations:
  198. proc `not`*(x: uint): uint {.magic: "BitnotI", noSideEffect.}
  199. ## Computes the `bitwise complement` of the integer `x`.
  200. proc `not`*(x: uint8): uint8 {.magic: "BitnotI", noSideEffect.}
  201. proc `not`*(x: uint16): uint16 {.magic: "BitnotI", noSideEffect.}
  202. proc `not`*(x: uint32): uint32 {.magic: "BitnotI", noSideEffect.}
  203. proc `not`*(x: uint64): uint64 {.magic: "BitnotI", noSideEffect.}
  204. proc `shr`*(x: uint, y: SomeInteger): uint {.magic: "ShrI", noSideEffect.}
  205. ## Computes the `shift right` operation of `x` and `y`.
  206. proc `shr`*(x: uint8, y: SomeInteger): uint8 {.magic: "ShrI", noSideEffect.}
  207. proc `shr`*(x: uint16, y: SomeInteger): uint16 {.magic: "ShrI", noSideEffect.}
  208. proc `shr`*(x: uint32, y: SomeInteger): uint32 {.magic: "ShrI", noSideEffect.}
  209. proc `shr`*(x: uint64, y: SomeInteger): uint64 {.magic: "ShrI", noSideEffect.}
  210. proc `shl`*(x: uint, y: SomeInteger): uint {.magic: "ShlI", noSideEffect.}
  211. ## Computes the `shift left` operation of `x` and `y`.
  212. proc `shl`*(x: uint8, y: SomeInteger): uint8 {.magic: "ShlI", noSideEffect.}
  213. proc `shl`*(x: uint16, y: SomeInteger): uint16 {.magic: "ShlI", noSideEffect.}
  214. proc `shl`*(x: uint32, y: SomeInteger): uint32 {.magic: "ShlI", noSideEffect.}
  215. proc `shl`*(x: uint64, y: SomeInteger): uint64 {.magic: "ShlI", noSideEffect.}
  216. proc `and`*(x, y: uint): uint {.magic: "BitandI", noSideEffect.}
  217. ## Computes the `bitwise and` of numbers `x` and `y`.
  218. proc `and`*(x, y: uint8): uint8 {.magic: "BitandI", noSideEffect.}
  219. proc `and`*(x, y: uint16): uint16 {.magic: "BitandI", noSideEffect.}
  220. proc `and`*(x, y: uint32): uint32 {.magic: "BitandI", noSideEffect.}
  221. proc `and`*(x, y: uint64): uint64 {.magic: "BitandI", noSideEffect.}
  222. proc `or`*(x, y: uint): uint {.magic: "BitorI", noSideEffect.}
  223. ## Computes the `bitwise or` of numbers `x` and `y`.
  224. proc `or`*(x, y: uint8): uint8 {.magic: "BitorI", noSideEffect.}
  225. proc `or`*(x, y: uint16): uint16 {.magic: "BitorI", noSideEffect.}
  226. proc `or`*(x, y: uint32): uint32 {.magic: "BitorI", noSideEffect.}
  227. proc `or`*(x, y: uint64): uint64 {.magic: "BitorI", noSideEffect.}
  228. proc `xor`*(x, y: uint): uint {.magic: "BitxorI", noSideEffect.}
  229. ## Computes the `bitwise xor` of numbers `x` and `y`.
  230. proc `xor`*(x, y: uint8): uint8 {.magic: "BitxorI", noSideEffect.}
  231. proc `xor`*(x, y: uint16): uint16 {.magic: "BitxorI", noSideEffect.}
  232. proc `xor`*(x, y: uint32): uint32 {.magic: "BitxorI", noSideEffect.}
  233. proc `xor`*(x, y: uint64): uint64 {.magic: "BitxorI", noSideEffect.}
  234. proc `+`*(x, y: uint): uint {.magic: "AddU", noSideEffect.}
  235. ## Binary `+` operator for unsigned integers.
  236. proc `+`*(x, y: uint8): uint8 {.magic: "AddU", noSideEffect.}
  237. proc `+`*(x, y: uint16): uint16 {.magic: "AddU", noSideEffect.}
  238. proc `+`*(x, y: uint32): uint32 {.magic: "AddU", noSideEffect.}
  239. proc `+`*(x, y: uint64): uint64 {.magic: "AddU", noSideEffect.}
  240. proc `-`*(x, y: uint): uint {.magic: "SubU", noSideEffect.}
  241. ## Binary `-` operator for unsigned integers.
  242. proc `-`*(x, y: uint8): uint8 {.magic: "SubU", noSideEffect.}
  243. proc `-`*(x, y: uint16): uint16 {.magic: "SubU", noSideEffect.}
  244. proc `-`*(x, y: uint32): uint32 {.magic: "SubU", noSideEffect.}
  245. proc `-`*(x, y: uint64): uint64 {.magic: "SubU", noSideEffect.}
  246. proc `*`*(x, y: uint): uint {.magic: "MulU", noSideEffect.}
  247. ## Binary `*` operator for unsigned integers.
  248. proc `*`*(x, y: uint8): uint8 {.magic: "MulU", noSideEffect.}
  249. proc `*`*(x, y: uint16): uint16 {.magic: "MulU", noSideEffect.}
  250. proc `*`*(x, y: uint32): uint32 {.magic: "MulU", noSideEffect.}
  251. proc `*`*(x, y: uint64): uint64 {.magic: "MulU", noSideEffect.}
  252. proc `div`*(x, y: uint): uint {.magic: "DivU", noSideEffect.}
  253. ## Computes the integer division for unsigned integers.
  254. ## This is roughly the same as `trunc(x/y)`.
  255. proc `div`*(x, y: uint8): uint8 {.magic: "DivU", noSideEffect.}
  256. proc `div`*(x, y: uint16): uint16 {.magic: "DivU", noSideEffect.}
  257. proc `div`*(x, y: uint32): uint32 {.magic: "DivU", noSideEffect.}
  258. proc `div`*(x, y: uint64): uint64 {.magic: "DivU", noSideEffect.}
  259. proc `mod`*(x, y: uint): uint {.magic: "ModU", noSideEffect.}
  260. ## Computes the integer modulo operation (remainder) for unsigned integers.
  261. ## This is the same as `x - (x div y) * y`.
  262. proc `mod`*(x, y: uint8): uint8 {.magic: "ModU", noSideEffect.}
  263. proc `mod`*(x, y: uint16): uint16 {.magic: "ModU", noSideEffect.}
  264. proc `mod`*(x, y: uint32): uint32 {.magic: "ModU", noSideEffect.}
  265. proc `mod`*(x, y: uint64): uint64 {.magic: "ModU", noSideEffect.}
  266. proc `+=`*[T: SomeInteger](x: var T, y: T) {.
  267. magic: "Inc", noSideEffect.}
  268. ## Increments an integer.
  269. proc `-=`*[T: SomeInteger](x: var T, y: T) {.
  270. magic: "Dec", noSideEffect.}
  271. ## Decrements an integer.
  272. proc `*=`*[T: SomeInteger](x: var T, y: T) {.
  273. inline, noSideEffect.} =
  274. ## Binary `*=` operator for integers.
  275. x = x * y
  276. # floating point operations:
  277. proc `+`*(x: float32): float32 {.magic: "UnaryPlusF64", noSideEffect.}
  278. proc `-`*(x: float32): float32 {.magic: "UnaryMinusF64", noSideEffect.}
  279. proc `+`*(x, y: float32): float32 {.magic: "AddF64", noSideEffect.}
  280. proc `-`*(x, y: float32): float32 {.magic: "SubF64", noSideEffect.}
  281. proc `*`*(x, y: float32): float32 {.magic: "MulF64", noSideEffect.}
  282. proc `/`*(x, y: float32): float32 {.magic: "DivF64", noSideEffect.}
  283. proc `+`*(x: float): float {.magic: "UnaryPlusF64", noSideEffect.}
  284. proc `-`*(x: float): float {.magic: "UnaryMinusF64", noSideEffect.}
  285. proc `+`*(x, y: float): float {.magic: "AddF64", noSideEffect.}
  286. proc `-`*(x, y: float): float {.magic: "SubF64", noSideEffect.}
  287. proc `*`*(x, y: float): float {.magic: "MulF64", noSideEffect.}
  288. proc `/`*(x, y: float): float {.magic: "DivF64", noSideEffect.}
  289. proc `+=`*[T: float|float32|float64] (x: var T, y: T) {.
  290. inline, noSideEffect.} =
  291. ## Increments in place a floating point number.
  292. x = x + y
  293. proc `-=`*[T: float|float32|float64] (x: var T, y: T) {.
  294. inline, noSideEffect.} =
  295. ## Decrements in place a floating point number.
  296. x = x - y
  297. proc `*=`*[T: float|float32|float64] (x: var T, y: T) {.
  298. inline, noSideEffect.} =
  299. ## Multiplies in place a floating point number.
  300. x = x * y
  301. proc `/=`*(x: var float64, y: float64) {.inline, noSideEffect.} =
  302. ## Divides in place a floating point number.
  303. x = x / y
  304. proc `/=`*[T: float|float32](x: var T, y: T) {.inline, noSideEffect.} =
  305. ## Divides in place a floating point number.
  306. x = x / y
  307. # the following have to be included in system, not imported for some reason:
  308. proc `+%`*(x, y: int): int {.inline.} =
  309. ## Treats `x` and `y` as unsigned and adds them.
  310. ##
  311. ## The result is truncated to fit into the result.
  312. ## This implements modulo arithmetic. No overflow errors are possible.
  313. cast[int](cast[uint](x) + cast[uint](y))
  314. proc `+%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) + cast[uint8](y))
  315. proc `+%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) + cast[uint16](y))
  316. proc `+%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) + cast[uint32](y))
  317. proc `+%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) + cast[uint64](y))
  318. proc `-%`*(x, y: int): int {.inline.} =
  319. ## Treats `x` and `y` as unsigned and subtracts them.
  320. ##
  321. ## The result is truncated to fit into the result.
  322. ## This implements modulo arithmetic. No overflow errors are possible.
  323. cast[int](cast[uint](x) - cast[uint](y))
  324. proc `-%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) - cast[uint8](y))
  325. proc `-%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) - cast[uint16](y))
  326. proc `-%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) - cast[uint32](y))
  327. proc `-%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) - cast[uint64](y))
  328. proc `*%`*(x, y: int): int {.inline.} =
  329. ## Treats `x` and `y` as unsigned and multiplies them.
  330. ##
  331. ## The result is truncated to fit into the result.
  332. ## This implements modulo arithmetic. No overflow errors are possible.
  333. cast[int](cast[uint](x) * cast[uint](y))
  334. proc `*%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) * cast[uint8](y))
  335. proc `*%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) * cast[uint16](y))
  336. proc `*%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) * cast[uint32](y))
  337. proc `*%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) * cast[uint64](y))
  338. proc `/%`*(x, y: int): int {.inline.} =
  339. ## Treats `x` and `y` as unsigned and divides them.
  340. ##
  341. ## The result is truncated to fit into the result.
  342. ## This implements modulo arithmetic. No overflow errors are possible.
  343. cast[int](cast[uint](x) div cast[uint](y))
  344. proc `/%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) div cast[uint8](y))
  345. proc `/%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) div cast[uint16](y))
  346. proc `/%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) div cast[uint32](y))
  347. proc `/%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) div cast[uint64](y))
  348. proc `%%`*(x, y: int): int {.inline.} =
  349. ## Treats `x` and `y` as unsigned and compute the modulo of `x` and `y`.
  350. ##
  351. ## The result is truncated to fit into the result.
  352. ## This implements modulo arithmetic. No overflow errors are possible.
  353. cast[int](cast[uint](x) mod cast[uint](y))
  354. proc `%%`*(x, y: int8): int8 {.inline.} = cast[int8](cast[uint8](x) mod cast[uint8](y))
  355. proc `%%`*(x, y: int16): int16 {.inline.} = cast[int16](cast[uint16](x) mod cast[uint16](y))
  356. proc `%%`*(x, y: int32): int32 {.inline.} = cast[int32](cast[uint32](x) mod cast[uint32](y))
  357. proc `%%`*(x, y: int64): int64 {.inline.} = cast[int64](cast[uint64](x) mod cast[uint64](y))