|
| 1 | +discard """ |
| 2 | + description: "Tests for the 128-bit integer implementation" |
| 3 | +""" |
| 4 | +import spec/int128 |
| 5 | + |
| 6 | +block parse_stringify_roundtrip: |
| 7 | + template test(str: string): bool = $parseInt128(str) == str |
| 8 | + |
| 9 | + doAssert test("12345678987654321012345678987") |
| 10 | + doAssert test("0") |
| 11 | + # leading zeroes: |
| 12 | + doAssert $parseInt128("0001") == "1" |
| 13 | + doAssert $parseInt128("-0001") == "-1" |
| 14 | + doAssert $parseInt128("-0") == "0" |
| 15 | + # trailing zeroes: |
| 16 | + doAssert test("10") |
| 17 | + doAssert test("-10") |
| 18 | + |
| 19 | +block negation: |
| 20 | + doAssert -toInt128(1) == toInt128(-1) |
| 21 | + doAssert -toInt128(0) == toInt128(0) |
| 22 | + |
| 23 | +var d: array[39, Int128] ## array of powers of 10 |
| 24 | +d[0] = parseInt128("1") |
| 25 | +d[1] = parseInt128("10") |
| 26 | +d[2] = parseInt128("100") |
| 27 | +d[3] = parseInt128("1000") |
| 28 | +d[4] = parseInt128("10000") |
| 29 | +d[5] = parseInt128("100000") |
| 30 | +d[6] = parseInt128("1000000") |
| 31 | +d[7] = parseInt128("10000000") |
| 32 | +d[8] = parseInt128("100000000") |
| 33 | +d[9] = parseInt128("1000000000") |
| 34 | +d[10] = parseInt128("10000000000") |
| 35 | +d[11] = parseInt128("100000000000") |
| 36 | +d[12] = parseInt128("1000000000000") |
| 37 | +d[13] = parseInt128("10000000000000") |
| 38 | +d[14] = parseInt128("100000000000000") |
| 39 | +d[15] = parseInt128("1000000000000000") |
| 40 | +d[16] = parseInt128("10000000000000000") |
| 41 | +d[17] = parseInt128("100000000000000000") |
| 42 | +d[18] = parseInt128("1000000000000000000") |
| 43 | +d[19] = parseInt128("10000000000000000000") |
| 44 | +d[20] = parseInt128("100000000000000000000") |
| 45 | +d[21] = parseInt128("1000000000000000000000") |
| 46 | +d[22] = parseInt128("10000000000000000000000") |
| 47 | +d[23] = parseInt128("100000000000000000000000") |
| 48 | +d[24] = parseInt128("1000000000000000000000000") |
| 49 | +d[25] = parseInt128("10000000000000000000000000") |
| 50 | +d[26] = parseInt128("100000000000000000000000000") |
| 51 | +d[27] = parseInt128("1000000000000000000000000000") |
| 52 | +d[28] = parseInt128("10000000000000000000000000000") |
| 53 | +d[29] = parseInt128("100000000000000000000000000000") |
| 54 | +d[30] = parseInt128("1000000000000000000000000000000") |
| 55 | +d[31] = parseInt128("10000000000000000000000000000000") |
| 56 | +d[32] = parseInt128("100000000000000000000000000000000") |
| 57 | +d[33] = parseInt128("1000000000000000000000000000000000") |
| 58 | +d[34] = parseInt128("10000000000000000000000000000000000") |
| 59 | +d[35] = parseInt128("100000000000000000000000000000000000") |
| 60 | +d[36] = parseInt128("1000000000000000000000000000000000000") |
| 61 | +d[37] = parseInt128("10000000000000000000000000000000000000") |
| 62 | +d[38] = parseInt128("100000000000000000000000000000000000000") |
| 63 | + |
| 64 | +block add_sub_test: |
| 65 | + # test addition: |
| 66 | + var sum: Int128 |
| 67 | + for it in d.items: |
| 68 | + sum = sum + it |
| 69 | + |
| 70 | + doAssert $sum == "111111111111111111111111111111111111111" |
| 71 | + |
| 72 | + # test subtraction: |
| 73 | + for it in d.items: |
| 74 | + sum = sum - it |
| 75 | + |
| 76 | + doAssert sum == Zero |
| 77 | + |
| 78 | +# test comparison, multiplication, and division with positive nubers: |
| 79 | +for i, a in d.pairs: |
| 80 | + for j, b in d.pairs: |
| 81 | + doAssert(cmp(a, b) == cmp(i, j)) |
| 82 | + if i + j < d.len: |
| 83 | + doAssert a * b == d[i + j] |
| 84 | + if i - j >= 0: |
| 85 | + doAssert a div b == d[i - j] |
| 86 | + |
| 87 | +# test comparison, multiplication, and division with negative nubers: |
| 88 | +for it in d.mitems: |
| 89 | + it = -it |
| 90 | + |
| 91 | +for i, a in d.pairs: |
| 92 | + for j, b in d.pairs: |
| 93 | + doAssert(cmp(a, b) == -cmp(i, j)) |
| 94 | + if i + j < d.len: |
| 95 | + doAssert a * b == -d[i + j] |
| 96 | + if i - j >= 0: |
| 97 | + doAssert a div b == -d[i - j] |
| 98 | + |
| 99 | +block sign_test: |
| 100 | + # ake sure the sign of quotients, remainders, and products is correct |
| 101 | + let |
| 102 | + a = 100'i64 |
| 103 | + b = 13 |
| 104 | + |
| 105 | + doAssert toInt128(a) * toInt128(0) == toInt128(0) |
| 106 | + doAssert toInt128(-a) * toInt128(0) == toInt128(0) |
| 107 | + |
| 108 | + template compare(a, b): bool = |
| 109 | + divMod(toInt128(a), toInt128(b)) == (toInt128(a div b), toInt128(a mod b)) |
| 110 | + |
| 111 | + doAssert compare( a, b) |
| 112 | + doAssert compare(-a, b) |
| 113 | + doAssert compare(-a, -b) |
| 114 | + doAssert compare( a, -b) |
| 115 | + |
| 116 | + doAssert compare( b, b) |
| 117 | + doAssert compare(-b, b) |
| 118 | + doAssert compare(-b, -b) |
| 119 | + doAssert compare( b, -b) |
| 120 | + |
| 121 | + doAssert compare( b, a) |
| 122 | + doAssert compare(-b, a) |
| 123 | + doAssert compare(-b, -a) |
| 124 | + doAssert compare( b, -a) |
| 125 | + |
| 126 | +# test logical left and right shift: |
| 127 | + |
| 128 | +proc toHex(i: Int128): string = |
| 129 | + var val = i |
| 130 | + while val != Zero: |
| 131 | + let (q, r) = udivMod(val, toInt128(16)) |
| 132 | + result.insert $"0123456789abcdef"[r.toInt] |
| 133 | + val = q |
| 134 | + |
| 135 | + # pad to 32 characters: |
| 136 | + for _ in result.len..<32: |
| 137 | + result.insert "0" |
| 138 | + |
| 139 | +let e = parseInt128("70997106675279150998592376708984375") |
| 140 | +let rshifted = [ |
| 141 | + # toHex(e shr 0), toHex(e shr 1), toHex(e shr 2), toHex(e shr 3), ... |
| 142 | + "000dac6d782d266a37300c32591eee37", "0006d636bc1693351b9806192c8f771b", "00036b1b5e0b499a8dcc030c9647bb8d", "0001b58daf05a4cd46e601864b23ddc6", |
| 143 | + "0000dac6d782d266a37300c32591eee3", "00006d636bc1693351b9806192c8f771", "000036b1b5e0b499a8dcc030c9647bb8", "00001b58daf05a4cd46e601864b23ddc", |
| 144 | + "00000dac6d782d266a37300c32591eee", "000006d636bc1693351b9806192c8f77", "0000036b1b5e0b499a8dcc030c9647bb", "000001b58daf05a4cd46e601864b23dd", |
| 145 | + "000000dac6d782d266a37300c32591ee", "0000006d636bc1693351b9806192c8f7", "00000036b1b5e0b499a8dcc030c9647b", "0000001b58daf05a4cd46e601864b23d", |
| 146 | + "0000000dac6d782d266a37300c32591e", "00000006d636bc1693351b9806192c8f", "000000036b1b5e0b499a8dcc030c9647", "00000001b58daf05a4cd46e601864b23", |
| 147 | + "00000000dac6d782d266a37300c32591", "000000006d636bc1693351b9806192c8", "0000000036b1b5e0b499a8dcc030c964", "000000001b58daf05a4cd46e601864b2", |
| 148 | + "000000000dac6d782d266a37300c3259", "0000000006d636bc1693351b9806192c", "00000000036b1b5e0b499a8dcc030c96", "0000000001b58daf05a4cd46e601864b", |
| 149 | + "0000000000dac6d782d266a37300c325", "00000000006d636bc1693351b9806192", "000000000036b1b5e0b499a8dcc030c9", "00000000001b58daf05a4cd46e601864", |
| 150 | + "00000000000dac6d782d266a37300c32", "000000000006d636bc1693351b980619", "0000000000036b1b5e0b499a8dcc030c", "000000000001b58daf05a4cd46e60186", |
| 151 | + "000000000000dac6d782d266a37300c3", "0000000000006d636bc1693351b98061", "00000000000036b1b5e0b499a8dcc030", "0000000000001b58daf05a4cd46e6018", |
| 152 | + "0000000000000dac6d782d266a37300c", "00000000000006d636bc1693351b9806", "000000000000036b1b5e0b499a8dcc03", "00000000000001b58daf05a4cd46e601", |
| 153 | + "00000000000000dac6d782d266a37300", "000000000000006d636bc1693351b980", "0000000000000036b1b5e0b499a8dcc0", "000000000000001b58daf05a4cd46e60", |
| 154 | + "000000000000000dac6d782d266a3730", "0000000000000006d636bc1693351b98", "00000000000000036b1b5e0b499a8dcc", "0000000000000001b58daf05a4cd46e6", |
| 155 | + "0000000000000000dac6d782d266a373", "00000000000000006d636bc1693351b9", "000000000000000036b1b5e0b499a8dc", "00000000000000001b58daf05a4cd46e", |
| 156 | + "00000000000000000dac6d782d266a37", "000000000000000006d636bc1693351b", "0000000000000000036b1b5e0b499a8d", "000000000000000001b58daf05a4cd46", |
| 157 | + "000000000000000000dac6d782d266a3", "0000000000000000006d636bc1693351", "00000000000000000036b1b5e0b499a8", "0000000000000000001b58daf05a4cd4", |
| 158 | + "0000000000000000000dac6d782d266a", "00000000000000000006d636bc169335", "000000000000000000036b1b5e0b499a", "00000000000000000001b58daf05a4cd", |
| 159 | + "00000000000000000000dac6d782d266", "000000000000000000006d636bc16933", "0000000000000000000036b1b5e0b499", "000000000000000000001b58daf05a4c", |
| 160 | + "000000000000000000000dac6d782d26", "0000000000000000000006d636bc1693", "00000000000000000000036b1b5e0b49", "0000000000000000000001b58daf05a4", |
| 161 | + "0000000000000000000000dac6d782d2", "00000000000000000000006d636bc169", "000000000000000000000036b1b5e0b4", "00000000000000000000001b58daf05a", |
| 162 | + "00000000000000000000000dac6d782d", "000000000000000000000006d636bc16", "0000000000000000000000036b1b5e0b", "000000000000000000000001b58daf05", |
| 163 | + "000000000000000000000000dac6d782", "0000000000000000000000006d636bc1", "00000000000000000000000036b1b5e0", "0000000000000000000000001b58daf0", |
| 164 | + "0000000000000000000000000dac6d78", "00000000000000000000000006d636bc", "000000000000000000000000036b1b5e", "00000000000000000000000001b58daf", |
| 165 | + "00000000000000000000000000dac6d7", "000000000000000000000000006d636b", "0000000000000000000000000036b1b5", "000000000000000000000000001b58da", |
| 166 | + "000000000000000000000000000dac6d", "0000000000000000000000000006d636", "00000000000000000000000000036b1b", "0000000000000000000000000001b58d", |
| 167 | + "0000000000000000000000000000dac6", "00000000000000000000000000006d63", "000000000000000000000000000036b1", "00000000000000000000000000001b58", |
| 168 | + "00000000000000000000000000000dac", "000000000000000000000000000006d6", "0000000000000000000000000000036b", "000000000000000000000000000001b5", |
| 169 | + "000000000000000000000000000000da", "0000000000000000000000000000006d", "00000000000000000000000000000036", "0000000000000000000000000000001b", |
| 170 | + "0000000000000000000000000000000d", "00000000000000000000000000000006", "00000000000000000000000000000003", "00000000000000000000000000000001", |
| 171 | + "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", |
| 172 | + "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", |
| 173 | + "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", "00000000000000000000000000000000", |
| 174 | +] |
| 175 | +let lshifted = [ |
| 176 | + # toHex(e shl 0), toHex(e shl 1), toHex(e shl 2), toHex(e shl 3), ... |
| 177 | + "000dac6d782d266a37300c32591eee37", "001b58daf05a4cd46e601864b23ddc6e", "0036b1b5e0b499a8dcc030c9647bb8dc", "006d636bc1693351b9806192c8f771b8", |
| 178 | + "00dac6d782d266a37300c32591eee370", "01b58daf05a4cd46e601864b23ddc6e0", "036b1b5e0b499a8dcc030c9647bb8dc0", "06d636bc1693351b9806192c8f771b80", |
| 179 | + "0dac6d782d266a37300c32591eee3700", "1b58daf05a4cd46e601864b23ddc6e00", "36b1b5e0b499a8dcc030c9647bb8dc00", "6d636bc1693351b9806192c8f771b800", |
| 180 | + "dac6d782d266a37300c32591eee37000", "b58daf05a4cd46e601864b23ddc6e000", "6b1b5e0b499a8dcc030c9647bb8dc000", "d636bc1693351b9806192c8f771b8000", |
| 181 | + "ac6d782d266a37300c32591eee370000", "58daf05a4cd46e601864b23ddc6e0000", "b1b5e0b499a8dcc030c9647bb8dc0000", "636bc1693351b9806192c8f771b80000", |
| 182 | + "c6d782d266a37300c32591eee3700000", "8daf05a4cd46e601864b23ddc6e00000", "1b5e0b499a8dcc030c9647bb8dc00000", "36bc1693351b9806192c8f771b800000", |
| 183 | + "6d782d266a37300c32591eee37000000", "daf05a4cd46e601864b23ddc6e000000", "b5e0b499a8dcc030c9647bb8dc000000", "6bc1693351b9806192c8f771b8000000", |
| 184 | + "d782d266a37300c32591eee370000000", "af05a4cd46e601864b23ddc6e0000000", "5e0b499a8dcc030c9647bb8dc0000000", "bc1693351b9806192c8f771b80000000", |
| 185 | + "782d266a37300c32591eee3700000000", "f05a4cd46e601864b23ddc6e00000000", "e0b499a8dcc030c9647bb8dc00000000", "c1693351b9806192c8f771b800000000", |
| 186 | + "82d266a37300c32591eee37000000000", "05a4cd46e601864b23ddc6e000000000", "0b499a8dcc030c9647bb8dc000000000", "1693351b9806192c8f771b8000000000", |
| 187 | + "2d266a37300c32591eee370000000000", "5a4cd46e601864b23ddc6e0000000000", "b499a8dcc030c9647bb8dc0000000000", "693351b9806192c8f771b80000000000", |
| 188 | + "d266a37300c32591eee3700000000000", "a4cd46e601864b23ddc6e00000000000", "499a8dcc030c9647bb8dc00000000000", "93351b9806192c8f771b800000000000", |
| 189 | + "266a37300c32591eee37000000000000", "4cd46e601864b23ddc6e000000000000", "99a8dcc030c9647bb8dc000000000000", "3351b9806192c8f771b8000000000000", |
| 190 | + "66a37300c32591eee370000000000000", "cd46e601864b23ddc6e0000000000000", "9a8dcc030c9647bb8dc0000000000000", "351b9806192c8f771b80000000000000", |
| 191 | + "6a37300c32591eee3700000000000000", "d46e601864b23ddc6e00000000000000", "a8dcc030c9647bb8dc00000000000000", "51b9806192c8f771b800000000000000", |
| 192 | + "a37300c32591eee37000000000000000", "46e601864b23ddc6e000000000000000", "8dcc030c9647bb8dc000000000000000", "1b9806192c8f771b8000000000000000", |
| 193 | + "37300c32591eee370000000000000000", "6e601864b23ddc6e0000000000000000", "dcc030c9647bb8dc0000000000000000", "b9806192c8f771b80000000000000000", |
| 194 | + "7300c32591eee3700000000000000000", "e601864b23ddc6e00000000000000000", "cc030c9647bb8dc00000000000000000", "9806192c8f771b800000000000000000", |
| 195 | + "300c32591eee37000000000000000000", "601864b23ddc6e000000000000000000", "c030c9647bb8dc000000000000000000", "806192c8f771b8000000000000000000", |
| 196 | + "00c32591eee370000000000000000000", "01864b23ddc6e0000000000000000000", "030c9647bb8dc0000000000000000000", "06192c8f771b80000000000000000000", |
| 197 | + "0c32591eee3700000000000000000000", "1864b23ddc6e00000000000000000000", "30c9647bb8dc00000000000000000000", "6192c8f771b800000000000000000000", |
| 198 | + "c32591eee37000000000000000000000", "864b23ddc6e000000000000000000000", "0c9647bb8dc000000000000000000000", "192c8f771b8000000000000000000000", |
| 199 | + "32591eee370000000000000000000000", "64b23ddc6e0000000000000000000000", "c9647bb8dc0000000000000000000000", "92c8f771b80000000000000000000000", |
| 200 | + "2591eee3700000000000000000000000", "4b23ddc6e00000000000000000000000", "9647bb8dc00000000000000000000000", "2c8f771b800000000000000000000000", |
| 201 | + "591eee37000000000000000000000000", "b23ddc6e000000000000000000000000", "647bb8dc000000000000000000000000", "c8f771b8000000000000000000000000", |
| 202 | + "91eee370000000000000000000000000", "23ddc6e0000000000000000000000000", "47bb8dc0000000000000000000000000", "8f771b80000000000000000000000000", |
| 203 | + "1eee3700000000000000000000000000", "3ddc6e00000000000000000000000000", "7bb8dc00000000000000000000000000", "f771b800000000000000000000000000", |
| 204 | + "eee37000000000000000000000000000", "ddc6e000000000000000000000000000", "bb8dc000000000000000000000000000", "771b8000000000000000000000000000", |
| 205 | + "ee370000000000000000000000000000", "dc6e0000000000000000000000000000", "b8dc0000000000000000000000000000", "71b80000000000000000000000000000", |
| 206 | + "e3700000000000000000000000000000", "c6e00000000000000000000000000000", "8dc00000000000000000000000000000", "1b800000000000000000000000000000", |
| 207 | + "37000000000000000000000000000000", "6e000000000000000000000000000000", "dc000000000000000000000000000000", "b8000000000000000000000000000000", |
| 208 | + "70000000000000000000000000000000", "e0000000000000000000000000000000", "c0000000000000000000000000000000", "80000000000000000000000000000000", |
| 209 | +] |
| 210 | + |
| 211 | +for i in 0 ..< 128: |
| 212 | + doAssert rshifted[i] == toHex(e shr i) |
| 213 | + doAssert lshifted[i] == toHex(e shl i) |
0 commit comments