| 1 | import math.unsigned |
| 2 | |
| 3 | fn test_str() { |
| 4 | // converting from a string and then back to a string |
| 5 | // should always give the original string. |
| 6 | test_strings := [ |
| 7 | '0', |
| 8 | '1', |
| 9 | '9', |
| 10 | '10', |
| 11 | '11', |
| 12 | '99', |
| 13 | '100', |
| 14 | '101', |
| 15 | '65534', |
| 16 | '65535', |
| 17 | '65536', // 16-bit boundary |
| 18 | '65537', |
| 19 | '65538', |
| 20 | '4294967294', |
| 21 | '4294967295', |
| 22 | '4294967296', // 32-bit boundary |
| 23 | '4294967297', |
| 24 | '4294967298', |
| 25 | '281474976710654', |
| 26 | '281474976710655', |
| 27 | '281474976710656', // 48-bit boundary, |
| 28 | '281474976710657', |
| 29 | '281474976710658', |
| 30 | '18446744073709551614', |
| 31 | '18446744073709551615', |
| 32 | '18446744073709551616', // 64-bit boundary |
| 33 | '18446744073709551617', |
| 34 | '18446744073709551618', |
| 35 | '1208925819614629174706174', |
| 36 | '1208925819614629174706175', |
| 37 | '1208925819614629174706176', // 80-bit boundary |
| 38 | '1208925819614629174706177', |
| 39 | '1208925819614629174706178', |
| 40 | '79228162514264337593543950334', |
| 41 | '79228162514264337593543950335', |
| 42 | '79228162514264337593543950336', // 96-bit boundary |
| 43 | '79228162514264337593543950337', |
| 44 | '79228162514264337593543950338', |
| 45 | '5192296858534827628530496329220094', |
| 46 | '5192296858534827628530496329220095', |
| 47 | '5192296858534827628530496329220096', // 112-bit boundary |
| 48 | '5192296858534827628530496329220097', |
| 49 | '5192296858534827628530496329220098', |
| 50 | '340282366920938463463374607431768211454', |
| 51 | '340282366920938463463374607431768211455', |
| 52 | '340282366920938463463374607431768211456', // 128-bit boundary |
| 53 | '340282366920938463463374607431768211457', |
| 54 | '340282366920938463463374607431768211458', |
| 55 | '22300745198530623141535718272648361505980414', |
| 56 | '22300745198530623141535718272648361505980415', |
| 57 | '22300745198530623141535718272648361505980416', // 144-bit boundary |
| 58 | '22300745198530623141535718272648361505980417', |
| 59 | '22300745198530623141535718272648361505980418', |
| 60 | '1461501637330902918203684832716283019655932542974', |
| 61 | '1461501637330902918203684832716283019655932542975', |
| 62 | '1461501637330902918203684832716283019655932542976', // 160-bit boundary |
| 63 | '1461501637330902918203684832716283019655932542977', |
| 64 | '1461501637330902918203684832716283019655932542978', |
| 65 | '95780971304118053647396689196894323976171195136475134', |
| 66 | '95780971304118053647396689196894323976171195136475135', |
| 67 | '95780971304118053647396689196894323976171195136475136', // 176-bit boundary |
| 68 | '95780971304118053647396689196894323976171195136475137', |
| 69 | '95780971304118053647396689196894323976171195136475138', |
| 70 | '6277101735386680763835789423207666416102355444464034512894', |
| 71 | '6277101735386680763835789423207666416102355444464034512895', |
| 72 | '6277101735386680763835789423207666416102355444464034512896', // 192-bit boundary |
| 73 | '6277101735386680763835789423207666416102355444464034512897', |
| 74 | '6277101735386680763835789423207666416102355444464034512898', |
| 75 | '411376139330301510538742295639337626245683966408394965837152254', |
| 76 | '411376139330301510538742295639337626245683966408394965837152255', |
| 77 | '411376139330301510538742295639337626245683966408394965837152256', // 208-bit boundary |
| 78 | '411376139330301510538742295639337626245683966408394965837152257', |
| 79 | '411376139330301510538742295639337626245683966408394965837152258', |
| 80 | '26959946667150639794667015087019630673637144422540572481103610249214', |
| 81 | '26959946667150639794667015087019630673637144422540572481103610249215', |
| 82 | '26959946667150639794667015087019630673637144422540572481103610249216', // 224-bit boundary |
| 83 | '26959946667150639794667015087019630673637144422540572481103610249217', |
| 84 | '26959946667150639794667015087019630673637144422540572481103610249218', |
| 85 | '1766847064778384329583297500742918515827483896875618958121606201292619774', |
| 86 | '1766847064778384329583297500742918515827483896875618958121606201292619775', |
| 87 | '1766847064778384329583297500742918515827483896875618958121606201292619776', // 240-bit boundary |
| 88 | '1766847064778384329583297500742918515827483896875618958121606201292619777', |
| 89 | '1766847064778384329583297500742918515827483896875618958121606201292619778', |
| 90 | '115792089237316195423570985008687907853269984665640564039457584007913129639934', |
| 91 | '115792089237316195423570985008687907853269984665640564039457584007913129639935', // 2^256 - 1 |
| 92 | ] |
| 93 | |
| 94 | for ts in test_strings { |
| 95 | number := unsigned.uint256_from_dec_str(ts) or { |
| 96 | assert false, 'invalid Uint256 string ${ts}' |
| 97 | panic('') |
| 98 | } |
| 99 | |
| 100 | assert number.str() == ts |
| 101 | } |
| 102 | |
| 103 | fundamental_constant := unsigned.uint256_from_64(42) |
| 104 | assert fundamental_constant.str() == '42' |
| 105 | } |
| 106 | |
| 107 | fn test_ops() { |
| 108 | x := unsigned.uint256_from_64(18446744073709551615) |
| 109 | y := unsigned.uint256_from_64(18446744073709551615) |
| 110 | z := unsigned.uint256_from_dec_str('340282366920938463426481119284349108225') or { |
| 111 | assert false |
| 112 | panic('') |
| 113 | } |
| 114 | assert (x * y).str() == '340282366920938463426481119284349108225' |
| 115 | assert (x + y).str() == '36893488147419103230' |
| 116 | assert (z / unsigned.uint256_from_64(2)).str() == '170141183460469231713240559642174554112' |
| 117 | assert (unsigned.uint256_from_dec_str('170141183460469231713240559642174554112') or { |
| 118 | panic('') |
| 119 | } - unsigned.uint256_from_64(2)).str() == '170141183460469231713240559642174554110' |
| 120 | |
| 121 | assert x == y |
| 122 | assert unsigned.uint256_from_dec_str('340282366920938463426481119284349108225') or { |
| 123 | assert false |
| 124 | panic('') |
| 125 | } > y |
| 126 | } |
| 127 | |
| 128 | struct LeadingZeros { |
| 129 | l unsigned.Uint256 |
| 130 | r unsigned.Uint256 |
| 131 | zeros int |
| 132 | } |
| 133 | |
| 134 | fn new(x unsigned.Uint128, y unsigned.Uint128) unsigned.Uint256 { |
| 135 | return unsigned.Uint256{x, y} |
| 136 | } |
| 137 | |
| 138 | fn test_leading_zeros() { |
| 139 | tcs := [ |
| 140 | LeadingZeros{ |
| 141 | l: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0xf000000000000000)) |
| 142 | r: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0x8000000000000000)) |
| 143 | zeros: 65 |
| 144 | }, |
| 145 | LeadingZeros{ |
| 146 | l: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0xf000000000000000)) |
| 147 | r: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0xc000000000000000)) |
| 148 | zeros: 66 |
| 149 | }, |
| 150 | LeadingZeros{ |
| 151 | l: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0xf000000000000000)) |
| 152 | r: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0xe000000000000000)) |
| 153 | zeros: 67 |
| 154 | }, |
| 155 | LeadingZeros{ |
| 156 | l: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0xffff000000000000)) |
| 157 | r: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0xff00000000000000)) |
| 158 | zeros: 72 |
| 159 | }, |
| 160 | LeadingZeros{ |
| 161 | l: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0x000000000000ffff)) |
| 162 | r: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0x000000000000ff00)) |
| 163 | zeros: 120 |
| 164 | }, |
| 165 | LeadingZeros{ |
| 166 | l: new(unsigned.uint128_from_64(0xf000000000000000), unsigned.uint128_from_64(0x01)) |
| 167 | r: new(unsigned.uint128_from_64(0x4000000000000000), unsigned.uint128_from_64(0x00)) |
| 168 | zeros: 127 |
| 169 | }, |
| 170 | LeadingZeros{ |
| 171 | l: new(unsigned.uint128_from_64(0xf000000000000000), unsigned.uint128_from_64(0x00)) |
| 172 | r: new(unsigned.uint128_from_64(0x4000000000000000), unsigned.uint128_from_64(0x00)) |
| 173 | zeros: 192 |
| 174 | }, |
| 175 | LeadingZeros{ |
| 176 | l: new(unsigned.uint128_from_64(0xf000000000000000), unsigned.uint128_from_64(0x00)) |
| 177 | r: new(unsigned.uint128_from_64(0x8000000000000000), unsigned.uint128_from_64(0x00)) |
| 178 | zeros: 193 |
| 179 | }, |
| 180 | LeadingZeros{ |
| 181 | l: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0x00)) |
| 182 | r: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0x00)) |
| 183 | zeros: 256 |
| 184 | }, |
| 185 | LeadingZeros{ |
| 186 | l: new(unsigned.uint128_from_64(0x01), unsigned.uint128_from_64(0x00)) |
| 187 | r: new(unsigned.uint128_from_64(0x00), unsigned.uint128_from_64(0x00)) |
| 188 | zeros: 255 |
| 189 | }, |
| 190 | ] |
| 191 | |
| 192 | for tc in tcs { |
| 193 | zeros := tc.l.xor(tc.r).leading_zeros() |
| 194 | assert zeros == tc.zeros |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | fn test_separators() { |
| 199 | // numbers of varying lengths and a random |
| 200 | // scattering of '_' throughout. |
| 201 | test_strings := [ |
| 202 | '_', |
| 203 | '__', |
| 204 | '_0', |
| 205 | '0_', |
| 206 | '_0_', |
| 207 | '_1', |
| 208 | '1_', |
| 209 | '_1_', |
| 210 | '1_2', |
| 211 | '_12', |
| 212 | '12_', |
| 213 | '12_3', |
| 214 | '1_23_4', |
| 215 | '12_345', |
| 216 | '_123_456_', |
| 217 | '1_234_567', |
| 218 | '1234_5678', |
| 219 | '_123456789', |
| 220 | '1234567890_', |
| 221 | '0_123_456_789_0', |
| 222 | '90_12_345_67890', |
| 223 | '8901_234_567890_', |
| 224 | '_7890_123456789_0', |
| 225 | '678901234_567890', |
| 226 | '567890_1234567890', |
| 227 | '4567890123__4567890', |
| 228 | '_34567890123_4567890', |
| 229 | '2345678_90123_4567890', |
| 230 | '123456789_01_234567890', |
| 231 | '01234567_8901234567890', |
| 232 | '9012345678901_234567890__', |
| 233 | '8_90123456_78901234567890', |
| 234 | '78901234567890_123_4567890', |
| 235 | '___67890123_4_5_6_78901234567890___', |
| 236 | '567890123_45678901234567890', |
| 237 | '45_67890123456789_01234567890', |
| 238 | '3456789012_345678901234567890', |
| 239 | '234_567890_1234_5__67890_1234567890_', |
| 240 | '12345678_90123_456789_0123_4567890', |
| 241 | '0_123_456_789_012_345_678_901_234_567_890', |
| 242 | '90_123456__78901__234567_8901_234567890', |
| 243 | '890123456789012345678901234567_890', |
| 244 | '7890_1234567_8901234567890_1234567890', |
| 245 | '67890123_45678_901234567_8901234567890', |
| 246 | '567890_1234567890_12345678901_234567890', |
| 247 | '45678_9012345_6789012345678901234567890_', |
| 248 | '34567890123456_789012345678901234567890', |
| 249 | '234567_890_1234567890_1234567890_1234567890', |
| 250 | '334567890_1234567890_1234567890_1234567890', |
| 251 | '340282360_0000000000_0000000000_0000000000', |
| 252 | '340282366_9209384634_2648111928_4349108225', |
| 253 | '340282366_9209384634_6337460743_1768211455', |
| 254 | '6805_647__338418769269_267492148635_36422912', |
| 255 | '13611294676837_5385385__34984297_27072845824_', |
| 256 | '272225893_53675077077_0699685_94_5414569_1648', |
| 257 | '_5444517_8707350154_1541_3993718908291383296', |
| 258 | '223007_45198_5306231_4153571_8272648_361505_980416_', |
| 259 | '146_150_163_733_090_291_820_368_483_271_628_301_965_593_254_297_6', |
| 260 | '6_27_71_01_7353866807638_35789423207666416_1_0_2355444464034512896', |
| 261 | '2695994_666715063_979466701508701_9630673637144422_540572481103610249216_', |
| 262 | '11579208_923731619_5423570985008687_907853269_98_46_656405640__39457584_00791_3129639935', |
| 263 | ] |
| 264 | |
| 265 | for ts in test_strings { |
| 266 | with := unsigned.uint256_from_dec_str(ts) or { |
| 267 | assert false, 'invalid Uint256 string ${ts}' |
| 268 | panic('') |
| 269 | } |
| 270 | |
| 271 | without := unsigned.uint256_from_dec_str(ts.replace('_', '')) or { |
| 272 | assert false, 'invalid Uint256 string ${ts.replace('_', '')}' |
| 273 | panic('') |
| 274 | } |
| 275 | |
| 276 | assert with == without |
| 277 | } |
| 278 | } |
| 279 | |
| 280 | fn test_new() { |
| 281 | assert unsigned.uint256_new(unsigned.uint128_max, unsigned.uint128_max) == unsigned.uint256_max |
| 282 | } |
| 283 | |
| 284 | fn test_rsh() { |
| 285 | a := |
| 286 | unsigned.uint256_from_dec_str('115792089237316195423570985008687907853269984665640564039457584007913129639935')! |
| 287 | assert a.str() == a.rsh(0).str() |
| 288 | assert '57896044618658097711785492504343953926634992332820282019728792003956564819967' == a.rsh(1).str() |
| 289 | assert '6277101735386680763835789423207666416102355444464034512895' == a.rsh(64).str() |
| 290 | assert '91343852333181432387730302044767688728495783935' == a.rsh(100).str() |
| 291 | assert '340282366920938463463374607431768211455' == a.rsh(128).str() |
| 292 | assert '170141183460469231731687303715884105727' == a.rsh(129).str() |
| 293 | assert unsigned.uint256_zero == a.rsh(256) |
| 294 | } |
| 295 | |
| 296 | fn test_lsh() { |
| 297 | a := unsigned.uint256_from_dec_str('123')! |
| 298 | assert a.lsh(0).str() == a.str() |
| 299 | assert a.lsh(1).str() == '246' |
| 300 | assert a.lsh(63).str() == '1134474760533137424384' |
| 301 | assert a.lsh(64).str() == '2268949521066274848768' |
| 302 | assert a.lsh(100).str() == '155921023828072216384094494261248' |
| 303 | assert a.lsh(128).str() == '41854731131275431005995076714107490009088' |
| 304 | assert a.lsh(200).str() == '197653379443855803891661337357963000110230968235283518742069248' |
| 305 | assert a.lsh(300) == unsigned.uint256_zero |
| 306 | } |
| 307 | |
| 308 | fn test_rotate_left() { |
| 309 | a := |
| 310 | unsigned.uint256_from_dec_str('25514942427378518882041616545065271187265095759155217686057363902268374351523')! |
| 311 | assert a.rotate_left(182).str() == '88706376393829417451765793453791860419270208590599379720310994108668904859637' |
| 312 | } |
| 313 | |