1const std = @import("std"); 2const expect = std.testing.expect; 3const expectEqual = std.testing.expectEqual; 4const expectEqualSlices = std.testing.expectEqualSlices; 5const maxInt = std.math.maxInt; 6const minInt = std.math.minInt; 7const mem = std.mem; 8 9test "assignment operators" { 10 var i: u32 = 0; 11 i += 5; 12 try expect(i == 5); 13 i -= 2; 14 try expect(i == 3); 15 i *= 20; 16 try expect(i == 60); 17 i /= 3; 18 try expect(i == 20); 19 i %= 11; 20 try expect(i == 9); 21 i <<= 1; 22 try expect(i == 18); 23 i >>= 2; 24 try expect(i == 4); 25 i = 6; 26 i &= 5; 27 try expect(i == 4); 28 i ^= 6; 29 try expect(i == 2); 30 i = 6; 31 i |= 3; 32 try expect(i == 7); 33} 34 35test "three expr in a row" { 36 try testThreeExprInARow(false, true); 37 comptime try testThreeExprInARow(false, true); 38} 39fn testThreeExprInARow(f: bool, t: bool) !void { 40 try assertFalse(f or f or f); 41 try assertFalse(t and t and f); 42 try assertFalse(1 | 2 | 4 != 7); 43 try assertFalse(3 ^ 6 ^ 8 != 13); 44 try assertFalse(7 & 14 & 28 != 4); 45 try assertFalse(9 << 1 << 2 != 9 << 3); 46 try assertFalse(90 >> 1 >> 2 != 90 >> 3); 47 try assertFalse(100 - 1 + 1000 != 1099); 48 try assertFalse(5 * 4 / 2 % 3 != 1); 49 try assertFalse(@as(i32, @as(i32, 5)) != 5); 50 try assertFalse(!!false); 51 try assertFalse(@as(i32, 7) != --(@as(i32, 7))); 52} 53fn assertFalse(b: bool) !void { 54 try expect(!b); 55} 56 57test "@clz" { 58 try testClz(); 59 comptime try testClz(); 60} 61 62fn testClz() !void { 63 try expect(testOneClz(u8, 0b10001010) == 0); 64 try expect(testOneClz(u8, 0b00001010) == 4); 65 try expect(testOneClz(u8, 0b00011010) == 3); 66 try expect(testOneClz(u8, 0b00000000) == 8); 67 try expect(testOneClz(u128, 0xffffffffffffffff) == 64); 68 try expect(testOneClz(u128, 0x10000000000000000) == 63); 69} 70 71fn testOneClz(comptime T: type, x: T) u32 { 72 return @clz(T, x); 73} 74 75test "const number literal" { 76 const one = 1; 77 const eleven = ten + one; 78 79 try expect(eleven == 11); 80} 81const ten = 10; 82 83test "float equality" { 84 const x: f64 = 0.012; 85 const y: f64 = x + 1.0; 86 87 try testFloatEqualityImpl(x, y); 88 comptime try testFloatEqualityImpl(x, y); 89} 90 91fn testFloatEqualityImpl(x: f64, y: f64) !void { 92 const y2 = x + 1.0; 93 try expect(y == y2); 94} 95 96test "hex float literal parsing" { 97 comptime try expect(0x1.0 == 1.0); 98} 99 100test "quad hex float literal parsing in range" { 101 const a = 0x1.af23456789bbaaab347645365cdep+5; 102 const b = 0x1.dedafcff354b6ae9758763545432p-9; 103 const c = 0x1.2f34dd5f437e849b4baab754cdefp+4534; 104 const d = 0x1.edcbff8ad76ab5bf46463233214fp-435; 105 _ = a; 106 _ = b; 107 _ = c; 108 _ = d; 109} 110 111test "underscore separator parsing" { 112 try expect(0_0_0_0 == 0); 113 try expect(1_234_567 == 1234567); 114 try expect(001_234_567 == 1234567); 115 try expect(0_0_1_2_3_4_5_6_7 == 1234567); 116 117 try expect(0b0_0_0_0 == 0); 118 try expect(0b1010_1010 == 0b10101010); 119 try expect(0b0000_1010_1010 == 0b10101010); 120 try expect(0b1_0_1_0_1_0_1_0 == 0b10101010); 121 122 try expect(0o0_0_0_0 == 0); 123 try expect(0o1010_1010 == 0o10101010); 124 try expect(0o0000_1010_1010 == 0o10101010); 125 try expect(0o1_0_1_0_1_0_1_0 == 0o10101010); 126 127 try expect(0x0_0_0_0 == 0); 128 try expect(0x1010_1010 == 0x10101010); 129 try expect(0x0000_1010_1010 == 0x10101010); 130 try expect(0x1_0_1_0_1_0_1_0 == 0x10101010); 131 132 try expect(123_456.789_000e1_0 == 123456.789000e10); 133 try expect(0_1_2_3_4_5_6.7_8_9_0_0_0e0_0_1_0 == 123456.789000e10); 134 135 try expect(0x1234_5678.9ABC_DEF0p-1_0 == 0x12345678.9ABCDEF0p-10); 136 try expect(0x1_2_3_4_5_6_7_8.9_A_B_C_D_E_F_0p-0_0_0_1_0 == 0x12345678.9ABCDEF0p-10); 137} 138 139test "hex float literal within range" { 140 const a = 0x1.0p16383; 141 const b = 0x0.1p16387; 142 const c = 0x1.0p-16382; 143 _ = a; 144 _ = b; 145 _ = c; 146} 147 148test "comptime_int addition" { 149 comptime { 150 try expect(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950); 151 try expect(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380); 152 } 153} 154 155test "comptime_int multiplication" { 156 comptime { 157 try expect( 158 45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567, 159 ); 160 try expect( 161 594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016, 162 ); 163 } 164} 165 166test "comptime_int shifting" { 167 comptime { 168 try expect((@as(u128, 1) << 127) == 0x80000000000000000000000000000000); 169 } 170} 171 172test "comptime_int multi-limb shift and mask" { 173 comptime { 174 var a = 0xefffffffa0000001eeeeeeefaaaaaaab; 175 176 try expect(@as(u32, a & 0xffffffff) == 0xaaaaaaab); 177 a >>= 32; 178 try expect(@as(u32, a & 0xffffffff) == 0xeeeeeeef); 179 a >>= 32; 180 try expect(@as(u32, a & 0xffffffff) == 0xa0000001); 181 a >>= 32; 182 try expect(@as(u32, a & 0xffffffff) == 0xefffffff); 183 a >>= 32; 184 185 try expect(a == 0); 186 } 187} 188 189test "comptime_int multi-limb partial shift right" { 190 comptime { 191 var a = 0x1ffffffffeeeeeeee; 192 a >>= 16; 193 try expect(a == 0x1ffffffffeeee); 194 } 195} 196 197test "xor" { 198 try test_xor(); 199 comptime try test_xor(); 200} 201 202fn test_xor() !void { 203 try testOneXor(0xFF, 0x00, 0xFF); 204 try testOneXor(0xF0, 0x0F, 0xFF); 205 try testOneXor(0xFF, 0xF0, 0x0F); 206 try testOneXor(0xFF, 0x0F, 0xF0); 207 try testOneXor(0xFF, 0xFF, 0x00); 208} 209 210fn testOneXor(a: u8, b: u8, c: u8) !void { 211 try expect(a ^ b == c); 212} 213 214test "comptime_int xor" { 215 comptime { 216 try expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); 217 try expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); 218 try expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x0000000000000000FFFFFFFFFFFFFFFF); 219 try expect(0x0000000000000000FFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFF0000000000000000); 220 try expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000000000000000000000000000); 221 try expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0x00000000FFFFFFFF00000000FFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); 222 try expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000FFFFFFFF00000000FFFFFFFF); 223 try expect(0x00000000FFFFFFFF00000000FFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFF00000000FFFFFFFF00000000); 224 } 225} 226 227test "comptime_int param and return" { 228 const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702); 229 try expect(a == 137114567242441932203689521744947848950); 230 231 const b = comptimeAdd(594491908217841670578297176641415611445982232488944558774612, 390603545391089362063884922208143568023166603618446395589768); 232 try expect(b == 985095453608931032642182098849559179469148836107390954364380); 233} 234 235fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int { 236 return a + b; 237} 238 239test "binary not" { 240 try expect(comptime x: { 241 break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101; 242 }); 243 try expect(comptime x: { 244 break :x ~@as(u64, 2147483647) == 18446744071562067968; 245 }); 246 try testBinaryNot(0b1010101010101010); 247} 248 249fn testBinaryNot(x: u16) !void { 250 try expect(~x == 0b0101010101010101); 251} 252 253test "division" { 254 try testDivision(); 255 comptime try testDivision(); 256} 257fn testDivision() !void { 258 try expect(div(u32, 13, 3) == 4); 259 try expect(div(f16, 1.0, 2.0) == 0.5); 260 try expect(div(f32, 1.0, 2.0) == 0.5); 261 262 try expect(divExact(u32, 55, 11) == 5); 263 try expect(divExact(i32, -55, 11) == -5); 264 try expect(divExact(f16, 55.0, 11.0) == 5.0); 265 try expect(divExact(f16, -55.0, 11.0) == -5.0); 266 try expect(divExact(f32, 55.0, 11.0) == 5.0); 267 try expect(divExact(f32, -55.0, 11.0) == -5.0); 268 269 try expect(divFloor(i32, 5, 3) == 1); 270 try expect(divFloor(i32, -5, 3) == -2); 271 try expect(divFloor(f16, 5.0, 3.0) == 1.0); 272 try expect(divFloor(f16, -5.0, 3.0) == -2.0); 273 try expect(divFloor(f32, 5.0, 3.0) == 1.0); 274 try expect(divFloor(f32, -5.0, 3.0) == -2.0); 275 try expect(divFloor(i32, -0x80000000, -2) == 0x40000000); 276 try expect(divFloor(i32, 0, -0x80000000) == 0); 277 try expect(divFloor(i32, -0x40000001, 0x40000000) == -2); 278 try expect(divFloor(i32, -0x80000000, 1) == -0x80000000); 279 try expect(divFloor(i32, 10, 12) == 0); 280 try expect(divFloor(i32, -14, 12) == -2); 281 try expect(divFloor(i32, -2, 12) == -1); 282 283 try expect(divTrunc(i32, 5, 3) == 1); 284 try expect(divTrunc(i32, -5, 3) == -1); 285 try expect(divTrunc(i32, 9, -10) == 0); 286 try expect(divTrunc(i32, -9, 10) == 0); 287 try expect(divTrunc(f16, 5.0, 3.0) == 1.0); 288 try expect(divTrunc(f16, -5.0, 3.0) == -1.0); 289 try expect(divTrunc(f16, 9.0, -10.0) == 0.0); 290 try expect(divTrunc(f16, -9.0, 10.0) == 0.0); 291 try expect(divTrunc(f32, 5.0, 3.0) == 1.0); 292 try expect(divTrunc(f32, -5.0, 3.0) == -1.0); 293 try expect(divTrunc(f32, 9.0, -10.0) == 0.0); 294 try expect(divTrunc(f32, -9.0, 10.0) == 0.0); 295 try expect(divTrunc(f64, 5.0, 3.0) == 1.0); 296 try expect(divTrunc(f64, -5.0, 3.0) == -1.0); 297 try expect(divTrunc(f64, 9.0, -10.0) == 0.0); 298 try expect(divTrunc(f64, -9.0, 10.0) == 0.0); 299 try expect(divTrunc(i32, 10, 12) == 0); 300 try expect(divTrunc(i32, -14, 12) == -1); 301 try expect(divTrunc(i32, -2, 12) == 0); 302 303 try expect(mod(i32, 10, 12) == 10); 304 try expect(mod(i32, -14, 12) == 10); 305 try expect(mod(i32, -2, 12) == 10); 306 307 comptime { 308 try expect( 309 1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600, 310 ); 311 try expect( 312 @rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600, 313 ); 314 try expect( 315 1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2, 316 ); 317 try expect( 318 @divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2, 319 ); 320 try expect( 321 @divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2, 322 ); 323 try expect( 324 @divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2, 325 ); 326 try expect( 327 4126227191251978491697987544882340798050766755606969681711 % 10 == 1, 328 ); 329 } 330} 331fn div(comptime T: type, a: T, b: T) T { 332 return a / b; 333} 334fn divExact(comptime T: type, a: T, b: T) T { 335 return @divExact(a, b); 336} 337fn divFloor(comptime T: type, a: T, b: T) T { 338 return @divFloor(a, b); 339} 340fn divTrunc(comptime T: type, a: T, b: T) T { 341 return @divTrunc(a, b); 342} 343fn mod(comptime T: type, a: T, b: T) T { 344 return @mod(a, b); 345} 346 347test "unsigned wrapping" { 348 try testUnsignedWrappingEval(maxInt(u32)); 349 comptime try testUnsignedWrappingEval(maxInt(u32)); 350} 351fn testUnsignedWrappingEval(x: u32) !void { 352 const zero = x +% 1; 353 try expect(zero == 0); 354 const orig = zero -% 1; 355 try expect(orig == maxInt(u32)); 356} 357 358test "signed wrapping" { 359 try testSignedWrappingEval(maxInt(i32)); 360 comptime try testSignedWrappingEval(maxInt(i32)); 361} 362fn testSignedWrappingEval(x: i32) !void { 363 const min_val = x +% 1; 364 try expect(min_val == minInt(i32)); 365 const max_val = min_val -% 1; 366 try expect(max_val == maxInt(i32)); 367} 368 369test "signed negation wrapping" { 370 try testSignedNegationWrappingEval(minInt(i16)); 371 comptime try testSignedNegationWrappingEval(minInt(i16)); 372} 373fn testSignedNegationWrappingEval(x: i16) !void { 374 try expect(x == -32768); 375 const neg = -%x; 376 try expect(neg == -32768); 377} 378 379test "unsigned negation wrapping" { 380 try testUnsignedNegationWrappingEval(1); 381 comptime try testUnsignedNegationWrappingEval(1); 382} 383fn testUnsignedNegationWrappingEval(x: u16) !void { 384 try expect(x == 1); 385 const neg = -%x; 386 try expect(neg == maxInt(u16)); 387} 388 389test "unsigned 64-bit division" { 390 try test_u64_div(); 391 comptime try test_u64_div(); 392} 393fn test_u64_div() !void { 394 const result = divWithResult(1152921504606846976, 34359738365); 395 try expect(result.quotient == 33554432); 396 try expect(result.remainder == 100663296); 397} 398fn divWithResult(a: u64, b: u64) DivResult { 399 return DivResult{ 400 .quotient = a / b, 401 .remainder = a % b, 402 }; 403} 404const DivResult = struct { 405 quotient: u64, 406 remainder: u64, 407}; 408 409test "truncating shift right" { 410 try testShrTrunc(maxInt(u16)); 411 comptime try testShrTrunc(maxInt(u16)); 412} 413fn testShrTrunc(x: u16) !void { 414 const shifted = x >> 1; 415 try expect(shifted == 32767); 416} 417 418test "f128" { 419 try test_f128(); 420 comptime try test_f128(); 421} 422 423fn make_f128(x: f128) f128 { 424 return x; 425} 426 427fn test_f128() !void { 428 try expect(@sizeOf(f128) == 16); 429 try expect(make_f128(1.0) == 1.0); 430 try expect(make_f128(1.0) != 1.1); 431 try expect(make_f128(1.0) > 0.9); 432 try expect(make_f128(1.0) >= 0.9); 433 try expect(make_f128(1.0) >= 1.0); 434 try should_not_be_zero(1.0); 435} 436 437fn should_not_be_zero(x: f128) !void { 438 try expect(x != 0.0); 439} 440 441test "128-bit multiplication" { 442 var a: i128 = 3; 443 var b: i128 = 2; 444 var c = a * b; 445 try expect(c == 6); 446} 447