master
   1const builtin = @import("builtin");
   2const std = @import("std");
   3const assert = std.debug.assert;
   4const expect = std.testing.expect;
   5const expectEqual = std.testing.expectEqual;
   6const expectEqualSlices = std.testing.expectEqualSlices;
   7const maxInt = std.math.maxInt;
   8const minInt = std.math.minInt;
   9const mem = std.mem;
  10const math = std.math;
  11
  12test "assignment operators" {
  13    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
  14    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  15    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
  16
  17    var i: u32 = 0;
  18    i += 5;
  19    try expect(i == 5);
  20    i -= 2;
  21    try expect(i == 3);
  22    i *= 20;
  23    try expect(i == 60);
  24    i /= 3;
  25    try expect(i == 20);
  26    i %= 11;
  27    try expect(i == 9);
  28    i <<= 1;
  29    try expect(i == 18);
  30    i >>= 2;
  31    try expect(i == 4);
  32    i = 6;
  33    i &= 5;
  34    try expect(i == 4);
  35    i ^= 6;
  36    try expect(i == 2);
  37    i = 6;
  38    i |= 3;
  39    try expect(i == 7);
  40}
  41
  42test "three expr in a row" {
  43    try testThreeExprInARow(false, true);
  44    try comptime testThreeExprInARow(false, true);
  45}
  46fn testThreeExprInARow(f: bool, t: bool) !void {
  47    try assertFalse(f or f or f);
  48    try assertFalse(t and t and f);
  49    try assertFalse(1 | 2 | 4 != 7);
  50    try assertFalse(3 ^ 6 ^ 8 != 13);
  51    try assertFalse(7 & 14 & 28 != 4);
  52    try assertFalse(9 << 1 << 2 != 9 << 3);
  53    try assertFalse(90 >> 1 >> 2 != 90 >> 3);
  54    try assertFalse(100 - 1 + 1000 != 1099);
  55    try assertFalse(5 * 4 / 2 % 3 != 1);
  56    try assertFalse(@as(i32, @as(i32, 5)) != 5);
  57    try assertFalse(!!false);
  58    try assertFalse(@as(i32, 7) != --(@as(i32, 7)));
  59}
  60fn assertFalse(b: bool) !void {
  61    try expect(!b);
  62}
  63
  64test "@clz" {
  65    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
  66    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  67    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
  68    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
  69
  70    try testClz();
  71    try comptime testClz();
  72}
  73
  74fn testClz() !void {
  75    try expect(testOneClz(u8, 0b10001010) == 0);
  76    try expect(testOneClz(u8, 0b00001010) == 4);
  77    try expect(testOneClz(u8, 0b00011010) == 3);
  78    try expect(testOneClz(u8, 0b00000000) == 8);
  79    try expect(testOneClz(i8, -1) == 0);
  80}
  81
  82test "@clz big ints" {
  83    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
  84    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
  85    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
  86    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
  87
  88    try testClzBigInts();
  89    try comptime testClzBigInts();
  90}
  91
  92fn testClzBigInts() !void {
  93    try expect(testOneClz(u128, 0xffffffffffffffff) == 64);
  94    try expect(testOneClz(u128, 0x10000000000000000) == 63);
  95}
  96
  97fn testOneClz(comptime T: type, x: T) u32 {
  98    return @clz(x);
  99}
 100
 101test "@clz vectors" {
 102    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 103    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
 104    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 105    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 106    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 107    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 108
 109    try testClzVectors();
 110    try comptime testClzVectors();
 111}
 112
 113fn testClzVectors() !void {
 114    if (comptime builtin.cpu.has(.loongarch, .lsx)) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/159529
 115
 116    const Vu4 = @Vector(64, u4);
 117    const Vu8 = @Vector(64, u8);
 118    const Vu128 = @Vector(64, u128);
 119
 120    @setEvalBranchQuota(10_000);
 121    try testOneClzVector(u8, 64, @as(Vu8, @splat(0b10001010)), @as(Vu4, @splat(0)));
 122    try testOneClzVector(u8, 64, @as(Vu8, @splat(0b00001010)), @as(Vu4, @splat(4)));
 123    try testOneClzVector(u8, 64, @as(Vu8, @splat(0b00011010)), @as(Vu4, @splat(3)));
 124    try testOneClzVector(u8, 64, @as(Vu8, @splat(0b00000000)), @as(Vu4, @splat(8)));
 125    try testOneClzVector(u128, 64, @as(Vu128, @splat(0xffffffffffffffff)), @as(Vu8, @splat(64)));
 126    try testOneClzVector(u128, 64, @as(Vu128, @splat(0x10000000000000000)), @as(Vu8, @splat(63)));
 127}
 128
 129fn testOneClzVector(
 130    comptime T: type,
 131    comptime len: u32,
 132    x: @Vector(len, T),
 133    expected: @Vector(len, u32),
 134) !void {
 135    try expectVectorsEqual(@clz(x), expected);
 136}
 137
 138fn expectVectorsEqual(a: anytype, b: anytype) !void {
 139    const len_a = @typeInfo(@TypeOf(a)).vector.len;
 140    const len_b = @typeInfo(@TypeOf(b)).vector.len;
 141    try expect(len_a == len_b);
 142    try expect(@reduce(.And, a == b));
 143}
 144
 145test "@ctz" {
 146    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 147    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 148    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 149    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 150
 151    try testCtz();
 152    try comptime testCtz();
 153}
 154
 155fn testCtz() !void {
 156    try expect(testOneCtz(u8, 0b10100000) == 5);
 157    try expect(testOneCtz(u8, 0b10001010) == 1);
 158    try expect(testOneCtz(u8, 0b00000000) == 8);
 159    try expect(testOneCtz(i8, -1) == 0);
 160    try expect(testOneCtz(i8, -2) == 1);
 161    try expect(testOneCtz(u16, 0b00000000) == 16);
 162}
 163
 164fn testOneCtz(comptime T: type, x: T) u32 {
 165    return @ctz(x);
 166}
 167
 168test "@ctz 128-bit integers" {
 169    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 170    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 171    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 172    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 173
 174    try testCtz128();
 175    try comptime testCtz128();
 176}
 177
 178fn testCtz128() !void {
 179    try expect(testOneCtz(u128, @as(u128, 0x40000000000000000000000000000000)) == 126);
 180    try expect(math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1)) == @as(u128, 0x80000000000000000000000000000000));
 181    try expect(testOneCtz(u128, @as(u128, 0x80000000000000000000000000000000)) == 127);
 182    try expect(testOneCtz(u128, math.rotl(u128, @as(u128, 0x40000000000000000000000000000000), @as(u8, 1))) == 127);
 183}
 184
 185test "@ctz vectors" {
 186    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 187    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
 188    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 189    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 190    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 191    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 192
 193    try testCtzVectors();
 194    try comptime testCtzVectors();
 195}
 196
 197fn testCtzVectors() !void {
 198    if (comptime builtin.cpu.has(.loongarch, .lsx)) return error.SkipZigTest; // https://github.com/llvm/llvm-project/issues/159529
 199
 200    const Vu4 = @Vector(64, u4);
 201    const Vu8 = @Vector(64, u8);
 202    @setEvalBranchQuota(10_000);
 203    try testOneCtzVector(u8, 64, @as(Vu8, @splat(0b10100000)), @as(Vu4, @splat(5)));
 204    try testOneCtzVector(u8, 64, @as(Vu8, @splat(0b10001010)), @as(Vu4, @splat(1)));
 205    try testOneCtzVector(u8, 64, @as(Vu8, @splat(0b00000000)), @as(Vu4, @splat(8)));
 206    try testOneCtzVector(u16, 64, @as(@Vector(64, u16), @splat(0b00000000)), @as(@Vector(64, u5), @splat(16)));
 207}
 208
 209fn testOneCtzVector(
 210    comptime T: type,
 211    comptime len: u32,
 212    x: @Vector(len, T),
 213    expected: @Vector(len, u32),
 214) !void {
 215    try expectVectorsEqual(@ctz(x), expected);
 216}
 217
 218test "const number literal" {
 219    const one = 1;
 220    const eleven = ten + one;
 221
 222    try expect(eleven == 11);
 223}
 224const ten = 10;
 225
 226test "float equality" {
 227    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 228    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 229
 230    const x: f64 = 0.012;
 231    const y: f64 = x + 1.0;
 232
 233    try testFloatEqualityImpl(x, y);
 234    try comptime testFloatEqualityImpl(x, y);
 235}
 236
 237fn testFloatEqualityImpl(x: f64, y: f64) !void {
 238    const y2 = x + 1.0;
 239    try expect(y == y2);
 240}
 241
 242test "hex float literal parsing" {
 243    comptime assert(0x1.0 == 1.0);
 244}
 245
 246test "hex float literal within range" {
 247    const a = 0x1.0p16383;
 248    const b = 0x0.1p16387;
 249    const c = 0x1.0p-16382;
 250    _ = a;
 251    _ = b;
 252    _ = c;
 253}
 254
 255test "quad hex float literal parsing in range" {
 256    const a = 0x1.af23456789bbaaab347645365cdep+5;
 257    const b = 0x1.dedafcff354b6ae9758763545432p-9;
 258    const c = 0x1.2f34dd5f437e849b4baab754cdefp+4534;
 259    const d = 0x1.edcbff8ad76ab5bf46463233214fp-435;
 260    _ = a;
 261    _ = b;
 262    _ = c;
 263    _ = d;
 264}
 265
 266test "underscore separator parsing" {
 267    try expect(1_234_567 == 1234567);
 268    try expect(1_234_567 == 1234567);
 269    try expect(1_2_3_4_5_6_7 == 1234567);
 270
 271    try expect(0b0_0_0_0 == 0);
 272    try expect(0b1010_1010 == 0b10101010);
 273    try expect(0b0000_1010_1010 == 0b10101010);
 274    try expect(0b1_0_1_0_1_0_1_0 == 0b10101010);
 275
 276    try expect(0o0_0_0_0 == 0);
 277    try expect(0o1010_1010 == 0o10101010);
 278    try expect(0o0000_1010_1010 == 0o10101010);
 279    try expect(0o1_0_1_0_1_0_1_0 == 0o10101010);
 280
 281    try expect(0x0_0_0_0 == 0);
 282    try expect(0x1010_1010 == 0x10101010);
 283    try expect(0x0000_1010_1010 == 0x10101010);
 284    try expect(0x1_0_1_0_1_0_1_0 == 0x10101010);
 285
 286    try expect(123_456.789_000e1_0 == 123456.789000e10);
 287    try expect(1_2_3_4_5_6.7_8_9_0_0_0e0_0_1_0 == 123456.789000e10);
 288
 289    try expect(0x1234_5678.9ABC_DEF0p-1_0 == 0x12345678.9ABCDEF0p-10);
 290    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);
 291}
 292
 293test "comptime_int addition" {
 294    comptime {
 295        try expect(35361831660712422535336160538497375248 + 101752735581729509668353361206450473702 == 137114567242441932203689521744947848950);
 296        try expect(594491908217841670578297176641415611445982232488944558774612 + 390603545391089362063884922208143568023166603618446395589768 == 985095453608931032642182098849559179469148836107390954364380);
 297    }
 298}
 299
 300test "comptime_int multiplication" {
 301    comptime {
 302        try expect(
 303            45960427431263824329884196484953148229 * 128339149605334697009938835852565949723 == 5898522172026096622534201617172456926982464453350084962781392314016180490567,
 304        );
 305        try expect(
 306            594491908217841670578297176641415611445982232488944558774612 * 390603545391089362063884922208143568023166603618446395589768 == 232210647056203049913662402532976186578842425262306016094292237500303028346593132411865381225871291702600263463125370016,
 307        );
 308    }
 309}
 310
 311test "comptime_int shifting" {
 312    comptime {
 313        try expect((@as(u128, 1) << 127) == 0x80000000000000000000000000000000);
 314    }
 315}
 316
 317test "comptime_int multi-limb shift and mask" {
 318    comptime {
 319        var a = 0xefffffffa0000001eeeeeeefaaaaaaab;
 320
 321        try expect(@as(u32, a & 0xffffffff) == 0xaaaaaaab);
 322        a >>= 32;
 323        try expect(@as(u32, a & 0xffffffff) == 0xeeeeeeef);
 324        a >>= 32;
 325        try expect(@as(u32, a & 0xffffffff) == 0xa0000001);
 326        a >>= 32;
 327        try expect(@as(u32, a & 0xffffffff) == 0xefffffff);
 328        a >>= 32;
 329
 330        try expect(a == 0);
 331    }
 332}
 333
 334test "comptime_int multi-limb partial shift right" {
 335    comptime {
 336        var a = 0x1ffffffffeeeeeeee;
 337        a >>= 16;
 338        try expect(a == 0x1ffffffffeeee);
 339    }
 340}
 341
 342test "xor" {
 343    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 344
 345    try test_xor();
 346    try comptime test_xor();
 347}
 348
 349fn test_xor() !void {
 350    try testOneXor(0xFF, 0x00, 0xFF);
 351    try testOneXor(0xF0, 0x0F, 0xFF);
 352    try testOneXor(0xFF, 0xF0, 0x0F);
 353    try testOneXor(0xFF, 0x0F, 0xF0);
 354    try testOneXor(0xFF, 0xFF, 0x00);
 355}
 356
 357fn testOneXor(a: u8, b: u8, c: u8) !void {
 358    try expect(a ^ b == c);
 359}
 360
 361test "comptime_int xor" {
 362    comptime {
 363        try expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0x00000000000000000000000000000000 == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
 364        try expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0x0000000000000000FFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
 365        try expect(0xFFFFFFFFFFFFFFFF0000000000000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x0000000000000000FFFFFFFFFFFFFFFF);
 366        try expect(0x0000000000000000FFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFFFFFFFFFF0000000000000000);
 367        try expect(0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000000000000000000000000000);
 368        try expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0x00000000FFFFFFFF00000000FFFFFFFF == 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF);
 369        try expect(0xFFFFFFFF00000000FFFFFFFF00000000 ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0x00000000FFFFFFFF00000000FFFFFFFF);
 370        try expect(0x00000000FFFFFFFF00000000FFFFFFFF ^ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF == 0xFFFFFFFF00000000FFFFFFFF00000000);
 371    }
 372}
 373
 374test "comptime_int param and return" {
 375    const a = comptimeAdd(35361831660712422535336160538497375248, 101752735581729509668353361206450473702);
 376    try expect(a == 137114567242441932203689521744947848950);
 377
 378    const b = comptimeAdd(594491908217841670578297176641415611445982232488944558774612, 390603545391089362063884922208143568023166603618446395589768);
 379    try expect(b == 985095453608931032642182098849559179469148836107390954364380);
 380}
 381
 382fn comptimeAdd(comptime a: comptime_int, comptime b: comptime_int) comptime_int {
 383    return a + b;
 384}
 385
 386fn not(comptime T: type, a: T) T {
 387    return ~a;
 388}
 389
 390test "binary not" {
 391    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 392    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 393
 394    try expect(not(u0, 0) == 0);
 395    try expect(not(u1, 0) == 1);
 396    try expect(not(u1, 1) == 0);
 397    try expect(not(u5, 0b01001) == 0b10110);
 398    try expect(not(u5, 0b10110) == 0b01001);
 399    try expect(not(u16, 0b10101010_10101010) == 0b01010101_01010101);
 400    try expect(not(u16, 0b01010101_01010101) == 0b10101010_10101010);
 401    try expect(not(u32, 0xAAAA_3333) == 0x5555_CCCC);
 402    try expect(not(u32, 0x5555_CCCC) == 0xAAAA_3333);
 403    try expect(not(u35, 0x4_1111_FFFF) == 0x3_EEEE_0000);
 404    try expect(not(u35, 0x3_EEEE_0000) == 0x4_1111_FFFF);
 405    try expect(not(u48, 0x4567_89AB_CDEF) == 0xBA98_7654_3210);
 406    try expect(not(u48, 0xBA98_7654_3210) == 0x4567_89AB_CDEF);
 407    try expect(not(u64, 0x0123_4567_89AB_CDEF) == 0xFEDC_BA98_7654_3210);
 408    try expect(not(u64, 0xFEDC_BA98_7654_3210) == 0x0123_4567_89AB_CDEF);
 409
 410    try expect(not(i0, 0) == 0);
 411    try expect(not(i1, 0) == -1);
 412    try expect(not(i1, -1) == 0);
 413    try expect(not(i5, -2) == 1);
 414    try expect(not(i5, 3) == -4);
 415    try expect(not(i32, 0) == -1);
 416    try expect(not(i32, -2147483648) == 2147483647);
 417    try expect(not(i64, -1) == 0);
 418    try expect(not(i64, 0) == -1);
 419
 420    try expect(comptime x: {
 421        break :x ~@as(u16, 0b1010101010101010) == 0b0101010101010101;
 422    });
 423    try expect(comptime x: {
 424        break :x ~@as(u64, 2147483647) == 18446744071562067968;
 425    });
 426    try expect(comptime x: {
 427        break :x ~@as(u0, 0) == 0;
 428    });
 429}
 430
 431test "binary not big int <= 128 bits" {
 432    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 433    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 434    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 435    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 436
 437    try expect(not(u65, 1) == 0x1_FFFFFFFF_FFFFFFFE);
 438    try expect(not(u65, 0x1_FFFFFFFF_FFFFFFFE) == 1);
 439
 440    try expect(not(u96, 0x01234567_89ABCDEF_00000001) == 0xFEDCBA98_76543210_FFFFFFFE);
 441    try expect(not(u96, 0xFEDCBA98_76543210_FFFFFFFE) == 0x01234567_89ABCDEF_00000001);
 442
 443    try expect(not(u128, 0xAAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA) == 0x55555555_55555555_55555555_55555555);
 444    try expect(not(u128, 0x55555555_55555555_55555555_55555555) == 0xAAAAAAAA_AAAAAAAA_AAAAAAAA_AAAAAAAA);
 445
 446    try expect(not(i65, -1) == 0);
 447    try expect(not(i65, 0) == -1);
 448    try expect(not(i65, -18446744073709551616) == 18446744073709551615);
 449    try expect(not(i65, 18446744073709551615) == -18446744073709551616);
 450
 451    try expect(not(i128, -1) == 0);
 452    try expect(not(i128, 0) == -1);
 453    try expect(not(i128, -200) == 199);
 454    try expect(not(i128, 199) == -200);
 455
 456    try expect(comptime x: {
 457        break :x ~@as(u128, 0x55555555_55555555_55555555_55555555) == 0xaaaaaaaa_aaaaaaaa_aaaaaaaa_aaaaaaaa;
 458    });
 459    try expect(comptime x: {
 460        break :x ~@as(i128, 0x55555555_55555555_55555555_55555555) == @as(i128, @bitCast(@as(u128, 0xaaaaaaaa_aaaaaaaa_aaaaaaaa_aaaaaaaa)));
 461    });
 462}
 463
 464test "division" {
 465    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 466    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 467    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 468    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 469
 470    try testIntDivision();
 471    try comptime testIntDivision();
 472
 473    try testFloatDivision();
 474    try comptime testFloatDivision();
 475}
 476
 477fn testIntDivision() !void {
 478    try expect(div(u32, 13, 3) == 4);
 479    try expect(div(u64, 13, 3) == 4);
 480    try expect(div(u8, 13, 3) == 4);
 481
 482    try expect(divExact(u32, 55, 11) == 5);
 483    try expect(divExact(i32, -55, 11) == -5);
 484    try expect(divExact(i64, -55, 11) == -5);
 485    try expect(divExact(i16, -55, 11) == -5);
 486
 487    try expect(divFloor(i32, 5, 3) == 1);
 488    try expect(divFloor(i32, -5, 3) == -2);
 489    try expect(divFloor(i32, -0x80000000, -2) == 0x40000000);
 490    try expect(divFloor(i32, 0, -0x80000000) == 0);
 491    try expect(divFloor(i32, -0x40000001, 0x40000000) == -2);
 492    try expect(divFloor(i32, -0x80000000, 1) == -0x80000000);
 493    try expect(divFloor(i32, 10, 12) == 0);
 494    try expect(divFloor(i32, -14, 12) == -2);
 495    try expect(divFloor(i32, -2, 12) == -1);
 496
 497    try expect(divFloor(i8, 5, 3) == 1);
 498    try expect(divFloor(i16, -5, 3) == -2);
 499    try expect(divFloor(i64, -0x80000000, -2) == 0x40000000);
 500    try expect(divFloor(i64, -0x40000001, 0x40000000) == -2);
 501
 502    try expect(divTrunc(i32, 5, 3) == 1);
 503    try expect(divTrunc(i32, -5, 3) == -1);
 504    try expect(divTrunc(i32, 9, -10) == 0);
 505    try expect(divTrunc(i32, -9, 10) == 0);
 506    try expect(divTrunc(i32, 10, 12) == 0);
 507    try expect(divTrunc(i32, -14, 12) == -1);
 508    try expect(divTrunc(i32, -2, 12) == 0);
 509
 510    try expect(mod(i32, 10, 12) == 10);
 511    try expect(mod(i32, -14, 12) == 10);
 512    try expect(mod(i32, -2, 12) == 10);
 513    try expect(mod(i32, 10, -12) == -2);
 514    try expect(mod(i32, -14, -12) == -2);
 515    try expect(mod(i32, -2, -12) == -2);
 516
 517    try expect(mod(i64, -118, 12) == 2);
 518    try expect(mod(u32, 10, 12) == 10);
 519    try expect(mod(i64, -14, 12) == 10);
 520    try expect(mod(i16, -2, 12) == 10);
 521    try expect(mod(i16, -118, 12) == 2);
 522    try expect(mod(i8, -2, 12) == 10);
 523
 524    try expect(rem(i64, -118, 12) == -10);
 525    try expect(rem(i32, 10, 12) == 10);
 526    try expect(rem(i32, -14, 12) == -2);
 527    try expect(rem(i32, -2, 12) == -2);
 528    try expect(rem(i32, 118, -12) == 10);
 529    try expect(rem(i32, -14, -12) == -2);
 530    try expect(rem(i16, -118, 12) == -10);
 531
 532    try expect(divTrunc(i20, 20, -5) == -4);
 533    try expect(divTrunc(i20, -20, -4) == 5);
 534
 535    comptime {
 536        try expect(
 537            1194735857077236777412821811143690633098347576 % 508740759824825164163191790951174292733114988 == 177254337427586449086438229241342047632117600,
 538        );
 539        try expect(
 540            @rem(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -177254337427586449086438229241342047632117600,
 541        );
 542        try expect(
 543            1194735857077236777412821811143690633098347576 / 508740759824825164163191790951174292733114988 == 2,
 544        );
 545        try expect(
 546            @divTrunc(-1194735857077236777412821811143690633098347576, 508740759824825164163191790951174292733114988) == -2,
 547        );
 548        try expect(
 549            @divTrunc(1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == -2,
 550        );
 551        try expect(
 552            @divTrunc(-1194735857077236777412821811143690633098347576, -508740759824825164163191790951174292733114988) == 2,
 553        );
 554        try expect(
 555            4126227191251978491697987544882340798050766755606969681711 % 10 == 1,
 556        );
 557    }
 558}
 559
 560fn testFloatDivision() !void {
 561    try expect(div(f32, 1.0, 2.0) == 0.5);
 562
 563    try expect(divExact(f32, 55.0, 11.0) == 5.0);
 564    try expect(divExact(f32, -55.0, 11.0) == -5.0);
 565
 566    try expect(divFloor(f32, 5.0, 3.0) == 1.0);
 567    try expect(divFloor(f32, -5.0, 3.0) == -2.0);
 568    try expect(divFloor(f32, 56.0, 9.0) == 6.0);
 569    try expect(divFloor(f32, 1053.0, -41.0) == -26.0);
 570    try expect(divFloor(f16, -43.0, 12.0) == -4.0);
 571    try expect(divFloor(f64, -90.0, -9.0) == 10.0);
 572
 573    try expect(divTrunc(f32, 5.0, 3.0) == 1.0);
 574    try expect(divTrunc(f32, -5.0, 3.0) == -1.0);
 575    try expect(divTrunc(f32, 9.0, -10.0) == 0.0);
 576    try expect(divTrunc(f32, -9.0, 10.0) == 0.0);
 577    try expect(divTrunc(f64, 5.0, 3.0) == 1.0);
 578    try expect(divTrunc(f64, -5.0, 3.0) == -1.0);
 579    try expect(divTrunc(f64, 9.0, -10.0) == 0.0);
 580    try expect(divTrunc(f64, -9.0, 10.0) == 0.0);
 581}
 582
 583test "large integer division" {
 584    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 585    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
 586    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
 587    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
 588    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 589    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 590
 591    {
 592        var numerator: u256 = 99999999999999999997315645440;
 593        var divisor: u256 = 10000000000000000000000000000;
 594        _ = .{ &numerator, &divisor };
 595        try expect(numerator / divisor == 9);
 596    }
 597    {
 598        var numerator: u256 = 99999999999999999999000000000000000000000;
 599        var divisor: u256 = 10000000000000000000000000000000000000000;
 600        _ = .{ &numerator, &divisor };
 601        try expect(numerator / divisor == 9);
 602    }
 603}
 604
 605test "division half-precision floats" {
 606    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 607    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 608    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 609
 610    try testDivisionFP16();
 611    try comptime testDivisionFP16();
 612}
 613
 614fn testDivisionFP16() !void {
 615    try expect(div(f16, 1.0, 2.0) == 0.5);
 616
 617    try expect(divExact(f16, 55.0, 11.0) == 5.0);
 618    try expect(divExact(f16, -55.0, 11.0) == -5.0);
 619
 620    try expect(divFloor(f16, 5.0, 3.0) == 1.0);
 621    try expect(divFloor(f16, -5.0, 3.0) == -2.0);
 622    try expect(divTrunc(f16, 5.0, 3.0) == 1.0);
 623    try expect(divTrunc(f16, -5.0, 3.0) == -1.0);
 624    try expect(divTrunc(f16, 9.0, -10.0) == 0.0);
 625    try expect(divTrunc(f16, -9.0, 10.0) == 0.0);
 626}
 627
 628fn div(comptime T: type, a: T, b: T) T {
 629    return a / b;
 630}
 631fn divExact(comptime T: type, a: T, b: T) T {
 632    return @divExact(a, b);
 633}
 634fn divFloor(comptime T: type, a: T, b: T) T {
 635    return @divFloor(a, b);
 636}
 637fn divTrunc(comptime T: type, a: T, b: T) T {
 638    return @divTrunc(a, b);
 639}
 640fn mod(comptime T: type, a: T, b: T) T {
 641    return @mod(a, b);
 642}
 643fn rem(comptime T: type, a: T, b: T) T {
 644    return @rem(a, b);
 645}
 646
 647test "unsigned wrapping" {
 648    try testUnsignedWrappingEval(maxInt(u32));
 649    try comptime testUnsignedWrappingEval(maxInt(u32));
 650}
 651fn testUnsignedWrappingEval(x: u32) !void {
 652    const zero = x +% 1;
 653    try expect(zero == 0);
 654    const orig = zero -% 1;
 655    try expect(orig == maxInt(u32));
 656}
 657
 658test "signed wrapping" {
 659    try testSignedWrappingEval(maxInt(i32));
 660    try comptime testSignedWrappingEval(maxInt(i32));
 661}
 662fn testSignedWrappingEval(x: i32) !void {
 663    const min_val = x +% 1;
 664    try expect(min_val == minInt(i32));
 665    const max_val = min_val -% 1;
 666    try expect(max_val == maxInt(i32));
 667}
 668
 669test "signed negation wrapping" {
 670    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 671
 672    try testSignedNegationWrappingEval(minInt(i16));
 673    try comptime testSignedNegationWrappingEval(minInt(i16));
 674}
 675fn testSignedNegationWrappingEval(x: i16) !void {
 676    try expect(x == -32768);
 677    const neg = -%x;
 678    try expect(neg == -32768);
 679}
 680
 681test "unsigned negation wrapping" {
 682    try testUnsignedNegationWrappingEval(1);
 683    try comptime testUnsignedNegationWrappingEval(1);
 684}
 685fn testUnsignedNegationWrappingEval(x: u16) !void {
 686    try expect(x == 1);
 687    const neg = -%x;
 688    try expect(neg == maxInt(u16));
 689}
 690
 691test "negation wrapping" {
 692    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 693    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 694
 695    try expectEqual(@as(u1, 1), negateWrap(u1, 1));
 696}
 697
 698fn negateWrap(comptime T: type, x: T) T {
 699    // This is specifically testing a safety-checked add, so
 700    // special case minInt(T) which would overflow otherwise.
 701    return if (x == minInt(T)) minInt(T) else ~x + 1;
 702}
 703
 704test "unsigned 64-bit division" {
 705    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 706    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 707
 708    try test_u64_div();
 709    try comptime test_u64_div();
 710}
 711fn test_u64_div() !void {
 712    const result = divWithResult(1152921504606846976, 34359738365);
 713    try expect(result.quotient == 33554432);
 714    try expect(result.remainder == 100663296);
 715}
 716fn divWithResult(a: u64, b: u64) DivResult {
 717    return DivResult{
 718        .quotient = a / b,
 719        .remainder = a % b,
 720    };
 721}
 722const DivResult = struct {
 723    quotient: u64,
 724    remainder: u64,
 725};
 726
 727test "bit shift a u1" {
 728    var x: u1 = 1;
 729    _ = &x;
 730    const y = x << 0;
 731    try expect(y == 1);
 732}
 733
 734test "truncating shift right" {
 735    try testShrTrunc(maxInt(u16));
 736    try comptime testShrTrunc(maxInt(u16));
 737}
 738fn testShrTrunc(x: u16) !void {
 739    const shifted = x >> 1;
 740    try expect(shifted == 32767);
 741}
 742
 743test "f128" {
 744    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 745    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 746    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 747    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 748
 749    try test_f128();
 750    try comptime test_f128();
 751}
 752
 753fn make_f128(x: f128) f128 {
 754    return x;
 755}
 756
 757fn test_f128() !void {
 758    try expect(@sizeOf(f128) == 16);
 759    try expect(make_f128(1.0) == 1.0);
 760    try expect(make_f128(1.0) != 1.1);
 761    try expect(make_f128(1.0) > 0.9);
 762    try expect(make_f128(1.0) >= 0.9);
 763    try expect(make_f128(1.0) >= 1.0);
 764    try should_not_be_zero(1.0);
 765}
 766
 767fn should_not_be_zero(x: f128) !void {
 768    try expect(x != 0.0);
 769}
 770
 771test "umax wrapped squaring" {
 772    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 773    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 774    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 775
 776    {
 777        var x: u4 = maxInt(u4);
 778        x *%= x;
 779        try expect(x == 1);
 780    }
 781    {
 782        var x: u8 = maxInt(u8);
 783        x *%= x;
 784        try expect(x == 1);
 785    }
 786    {
 787        var x: u12 = maxInt(u12);
 788        x *%= x;
 789        try expect(x == 1);
 790    }
 791    {
 792        var x: u16 = maxInt(u16);
 793        x *%= x;
 794        try expect(x == 1);
 795    }
 796    {
 797        var x: u24 = maxInt(u24);
 798        x *%= x;
 799        try expect(x == 1);
 800    }
 801    {
 802        var x: u32 = maxInt(u32);
 803        x *%= x;
 804        try expect(x == 1);
 805    }
 806    {
 807        var x: u48 = maxInt(u48);
 808        x *%= x;
 809        try expect(x == 1);
 810    }
 811    {
 812        var x: u64 = maxInt(u64);
 813        x *%= x;
 814        try expect(x == 1);
 815    }
 816    {
 817        var x: u96 = maxInt(u96);
 818        x *%= x;
 819        try expect(x == 1);
 820    }
 821    {
 822        var x: u128 = maxInt(u128);
 823        x *%= x;
 824        try expect(x == 1);
 825    }
 826}
 827
 828test "128-bit multiplication" {
 829    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 830    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 831    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 832    if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
 833    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 834
 835    {
 836        var a: i128 = 3;
 837        var b: i128 = 2;
 838        var c = a * b;
 839        try expect(c == 6);
 840
 841        a = -3;
 842        b = 2;
 843        c = a * b;
 844        try expect(c == -6);
 845    }
 846
 847    {
 848        var a: u128 = 0xffffffffffffffff;
 849        var b: u128 = 100;
 850        _ = .{ &a, &b };
 851        const c = a * b;
 852        try expect(c == 0x63ffffffffffffff9c);
 853    }
 854}
 855
 856fn testAddWithOverflow(comptime T: type, a: T, b: T, add: T, bit: u1) !void {
 857    const ov = @addWithOverflow(a, b);
 858    try expect(ov[0] == add);
 859    try expect(ov[1] == bit);
 860}
 861
 862test "@addWithOverflow" {
 863    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 864    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 865    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
 866
 867    try testAddWithOverflow(u8, 250, 100, 94, 1);
 868    try testAddWithOverflow(u8, 100, 150, 250, 0);
 869
 870    try testAddWithOverflow(u8, 200, 99, 43, 1);
 871    try testAddWithOverflow(u8, 200, 55, 255, 0);
 872
 873    try testAddWithOverflow(usize, 6, 6, 12, 0);
 874    try testAddWithOverflow(usize, maxInt(usize), 6, 5, 1);
 875
 876    try testAddWithOverflow(isize, -6, -6, -12, 0);
 877    try testAddWithOverflow(isize, minInt(isize), -6, maxInt(isize) - 5, 1);
 878}
 879
 880test "@addWithOverflow > 64 bits" {
 881    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 882    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 883    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 884    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
 885
 886    try testAddWithOverflow(u65, 4, 105, 109, 0);
 887    try testAddWithOverflow(u65, 1000, 100, 1100, 0);
 888    try testAddWithOverflow(u65, 100, maxInt(u65) - 99, 0, 1);
 889    try testAddWithOverflow(u65, maxInt(u65), maxInt(u65), maxInt(u65) - 1, 1);
 890    try testAddWithOverflow(u65, maxInt(u65) - 1, maxInt(u65), maxInt(u65) - 2, 1);
 891    try testAddWithOverflow(u65, maxInt(u65), maxInt(u65) - 1, maxInt(u65) - 2, 1);
 892
 893    try testAddWithOverflow(u128, 4, 105, 109, 0);
 894    try testAddWithOverflow(u128, 1000, 100, 1100, 0);
 895    try testAddWithOverflow(u128, 100, maxInt(u128) - 99, 0, 1);
 896    try testAddWithOverflow(u128, maxInt(u128), maxInt(u128), maxInt(u128) - 1, 1);
 897    try testAddWithOverflow(u128, maxInt(u128) - 1, maxInt(u128), maxInt(u128) - 2, 1);
 898    try testAddWithOverflow(u128, maxInt(u128), maxInt(u128) - 1, maxInt(u128) - 2, 1);
 899
 900    try testAddWithOverflow(i65, 4, -105, -101, 0);
 901    try testAddWithOverflow(i65, 1000, 100, 1100, 0);
 902    try testAddWithOverflow(i65, minInt(i65), 1, minInt(i65) + 1, 0);
 903    try testAddWithOverflow(i65, maxInt(i65), minInt(i65), -1, 0);
 904    try testAddWithOverflow(i65, minInt(i65), maxInt(i65), -1, 0);
 905    try testAddWithOverflow(i65, maxInt(i65), -2, maxInt(i65) - 2, 0);
 906    try testAddWithOverflow(i65, maxInt(i65), maxInt(i65), -2, 1);
 907    try testAddWithOverflow(i65, minInt(i65), minInt(i65), 0, 1);
 908    try testAddWithOverflow(i65, maxInt(i65) - 1, maxInt(i65), -3, 1);
 909    try testAddWithOverflow(i65, maxInt(i65), maxInt(i65) - 1, -3, 1);
 910
 911    try testAddWithOverflow(i128, 4, -105, -101, 0);
 912    try testAddWithOverflow(i128, 1000, 100, 1100, 0);
 913    try testAddWithOverflow(i128, minInt(i128), 1, minInt(i128) + 1, 0);
 914    try testAddWithOverflow(i128, maxInt(i128), minInt(i128), -1, 0);
 915    try testAddWithOverflow(i128, minInt(i128), maxInt(i128), -1, 0);
 916    try testAddWithOverflow(i128, maxInt(i128), -2, maxInt(i128) - 2, 0);
 917    try testAddWithOverflow(i128, maxInt(i128), maxInt(i128), -2, 1);
 918    try testAddWithOverflow(i128, minInt(i128), minInt(i128), 0, 1);
 919    try testAddWithOverflow(i128, maxInt(i128) - 1, maxInt(i128), -3, 1);
 920    try testAddWithOverflow(i128, maxInt(i128), maxInt(i128) - 1, -3, 1);
 921}
 922
 923test "small int addition" {
 924    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 925    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
 926    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
 927
 928    var x: u2 = 0;
 929    try expect(x == 0);
 930
 931    x += 1;
 932    try expect(x == 1);
 933
 934    x += 1;
 935    try expect(x == 2);
 936
 937    x += 1;
 938    try expect(x == 3);
 939
 940    const ov = @addWithOverflow(x, 1);
 941    try expect(ov[0] == 0);
 942    try expect(ov[1] == 1);
 943}
 944
 945fn testMulWithOverflow(comptime T: type, a: T, b: T, mul: T, bit: u1) !void {
 946    const ov = @mulWithOverflow(a, b);
 947    try expect(ov[0] == mul);
 948    try expect(ov[1] == bit);
 949}
 950
 951test "basic @mulWithOverflow" {
 952    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 953    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 954    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest; // TODO
 955
 956    try testMulWithOverflow(u8, 86, 3, 2, 1);
 957    try testMulWithOverflow(u8, 85, 3, 255, 0);
 958
 959    try testMulWithOverflow(u8, 123, 2, 246, 0);
 960    try testMulWithOverflow(u8, 123, 4, 236, 1);
 961}
 962
 963test "extensive @mulWithOverflow" {
 964    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
 965    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
 966    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
 967    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
 968
 969    try testMulWithOverflow(u5, 3, 10, 30, 0);
 970    try testMulWithOverflow(u5, 3, 11, 1, 1);
 971    try testMulWithOverflow(i5, 3, -5, -15, 0);
 972    try testMulWithOverflow(i5, 3, -6, 14, 1);
 973
 974    try testMulWithOverflow(u8, 3, 85, 255, 0);
 975    try testMulWithOverflow(u8, 3, 86, 2, 1);
 976    try testMulWithOverflow(i8, 3, -42, -126, 0);
 977    try testMulWithOverflow(i8, 3, -43, 127, 1);
 978
 979    try testMulWithOverflow(u14, 3, 0x1555, 0x3fff, 0);
 980    try testMulWithOverflow(u14, 3, 0x1556, 2, 1);
 981    try testMulWithOverflow(i14, 3, -0xaaa, -0x1ffe, 0);
 982    try testMulWithOverflow(i14, 3, -0xaab, 0x1fff, 1);
 983
 984    try testMulWithOverflow(u16, 3, 0x5555, 0xffff, 0);
 985    try testMulWithOverflow(u16, 3, 0x5556, 2, 1);
 986    try testMulWithOverflow(i16, 3, -0x2aaa, -0x7ffe, 0);
 987    try testMulWithOverflow(i16, 3, -0x2aab, 0x7fff, 1);
 988
 989    try testMulWithOverflow(u30, 3, 0x15555555, 0x3fffffff, 0);
 990    try testMulWithOverflow(u30, 3, 0x15555556, 2, 1);
 991    try testMulWithOverflow(i30, 3, -0xaaaaaaa, -0x1ffffffe, 0);
 992    try testMulWithOverflow(i30, 3, -0xaaaaaab, 0x1fffffff, 1);
 993
 994    try testMulWithOverflow(u32, 3, 0x55555555, 0xffffffff, 0);
 995    try testMulWithOverflow(u32, 3, 0x55555556, 2, 1);
 996    try testMulWithOverflow(i32, 3, -0x2aaaaaaa, -0x7ffffffe, 0);
 997    try testMulWithOverflow(i32, 3, -0x2aaaaaab, 0x7fffffff, 1);
 998
 999    try testMulWithOverflow(u31, 1 << 30, 1 << 30, 0, 1);
1000    try testMulWithOverflow(i31, minInt(i31), minInt(i31), 0, 1);
1001}
1002
1003test "@mulWithOverflow bitsize > 32" {
1004    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1005    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1006    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1007    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1008
1009    try testMulWithOverflow(u40, 3, 0x55_5555_5555, 0xff_ffff_ffff, 0);
1010    try testMulWithOverflow(u40, 3, 0x55_5555_5556, 2, 1);
1011    try testMulWithOverflow(u40, 0x10_0000_0000, 0x10_0000_0000, 0, 1);
1012
1013    try testMulWithOverflow(i40, 3, -0x2a_aaaa_aaaa, -0x7f_ffff_fffe, 0);
1014    try testMulWithOverflow(i40, 3, -0x2a_aaaa_aaab, 0x7f_ffff_ffff, 1);
1015    try testMulWithOverflow(i40, 6, -0x2a_aaaa_aaab, -2, 1);
1016    try testMulWithOverflow(i40, 0x08_0000_0000, -0x08_0000_0001, -0x8_0000_0000, 1);
1017
1018    try testMulWithOverflow(u62, 3, 0x1555555555555555, 0x3fffffffffffffff, 0);
1019    try testMulWithOverflow(u62, 3, 0x1555555555555556, 2, 1);
1020    try testMulWithOverflow(i62, 3, -0xaaaaaaaaaaaaaaa, -0x1ffffffffffffffe, 0);
1021    try testMulWithOverflow(i62, 3, -0xaaaaaaaaaaaaaab, 0x1fffffffffffffff, 1);
1022
1023    try testMulWithOverflow(u64, 3, 0x5555555555555555, 0xffffffffffffffff, 0);
1024    try testMulWithOverflow(u64, 3, 0x5555555555555556, 2, 1);
1025    try testMulWithOverflow(i64, 3, -0x2aaaaaaaaaaaaaaa, -0x7ffffffffffffffe, 0);
1026    try testMulWithOverflow(i64, 3, -0x2aaaaaaaaaaaaaab, 0x7fffffffffffffff, 1);
1027
1028    try testMulWithOverflow(u63, 1 << 62, 1 << 62, 0, 1);
1029    try testMulWithOverflow(i63, minInt(i63), minInt(i63), 0, 1);
1030}
1031
1032test "@mulWithOverflow bitsize 128 bits" {
1033    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1034    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1035    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1036    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1037    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1038    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1039
1040    try testMulWithOverflow(u128, 3, 0x5555555555555555_5555555555555555, 0xffffffffffffffff_ffffffffffffffff, 0);
1041    try testMulWithOverflow(u128, 3, 0x5555555555555555_5555555555555556, 2, 1);
1042
1043    try testMulWithOverflow(u128, 1 << 100, 1 << 27, 1 << 127, 0);
1044    try testMulWithOverflow(u128, maxInt(u128), maxInt(u128), 1, 1);
1045    try testMulWithOverflow(u128, 1 << 100, 1 << 28, 0, 1);
1046    try testMulWithOverflow(u128, 1 << 127, 1 << 127, 0, 1);
1047
1048    try testMulWithOverflow(i128, 3, -0x2aaaaaaaaaaaaaaa_aaaaaaaaaaaaaaaa, -0x7fffffffffffffff_fffffffffffffffe, 0);
1049    try testMulWithOverflow(i128, 3, -0x2aaaaaaaaaaaaaaa_aaaaaaaaaaaaaaab, 0x7fffffffffffffff_ffffffffffffffff, 1);
1050    try testMulWithOverflow(i128, -1, -1, 1, 0);
1051    try testMulWithOverflow(i128, minInt(i128), minInt(i128), 0, 1);
1052
1053    try testMulWithOverflow(i128, 1 << 126, 1 << 1, -1 << 127, 1);
1054    try testMulWithOverflow(i128, -1 << 105, 1 << 22, -1 << 127, 0);
1055    try testMulWithOverflow(i128, 1 << 84, -1 << 43, -1 << 127, 0);
1056    try testMulWithOverflow(i128, -1 << 63, -1 << 64, -1 << 127, 1);
1057}
1058
1059test "@mulWithOverflow bitsize 256 bits" {
1060    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1061    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
1062    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
1063    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1064    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1065
1066    {
1067        const const_lhs: u256 = 8035709466408580321693645878924206181189;
1068        const const_rhs: u256 = 343954217539185679456797259115612849079;
1069        const const_result = @mulWithOverflow(const_lhs, const_rhs);
1070        comptime assert(const_result[0] == 100698109432518020450541558444080472799095368135495022414802684874680804056403);
1071        comptime assert(const_result[1] == 1);
1072
1073        var var_lhs = const_lhs;
1074        var var_rhs = const_rhs;
1075        _ = .{ &var_lhs, &var_rhs };
1076        const var_result = @mulWithOverflow(var_lhs, var_rhs);
1077        try std.testing.expect(var_result[0] == const_result[0]);
1078        try std.testing.expect(var_result[1] == const_result[1]);
1079    }
1080    {
1081        const const_lhs: u256 = 100477140835310762407466294984162740292250605075409128262608;
1082        const const_rhs: u256 = 406310585934439581231;
1083        const const_result = @mulWithOverflow(const_lhs, const_rhs);
1084        comptime assert(const_result[0] == 66110554277021146912650321519727251744526528332039438002889524600764482652976);
1085        comptime assert(const_result[1] == 1);
1086
1087        var var_lhs = const_lhs;
1088        var var_rhs = const_rhs;
1089        _ = .{ &var_lhs, &var_rhs };
1090        const var_result = @mulWithOverflow(var_lhs, var_rhs);
1091        try std.testing.expect(var_result[0] == const_result[0]);
1092        try std.testing.expect(var_result[1] == const_result[1]);
1093    }
1094    try testMulWithOverflow(i256, 1 << 254, 1 << 1, -1 << 255, 1);
1095    try testMulWithOverflow(i256, -1 << 212, 1 << 43, -1 << 255, 0);
1096    try testMulWithOverflow(i256, 1 << 170, -1 << 85, -1 << 255, 0);
1097    try testMulWithOverflow(i256, -1 << 128, -1 << 127, -1 << 255, 1);
1098}
1099
1100fn testSubWithOverflow(comptime T: type, a: T, b: T, sub: T, bit: u1) !void {
1101    const ov = @subWithOverflow(a, b);
1102    try expect(ov[0] == sub);
1103    try expect(ov[1] == bit);
1104}
1105
1106test "@subWithOverflow" {
1107    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1108    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1109
1110    try testSubWithOverflow(u8, 1, 2, 255, 1);
1111    try testSubWithOverflow(u8, 1, 1, 0, 0);
1112
1113    try testSubWithOverflow(u16, 10000, 10002, 65534, 1);
1114    try testSubWithOverflow(u16, 10000, 9999, 1, 0);
1115
1116    try testSubWithOverflow(usize, 6, 6, 0, 0);
1117    try testSubWithOverflow(usize, 6, 7, maxInt(usize), 1);
1118    try testSubWithOverflow(isize, -6, -6, 0, 0);
1119    try testSubWithOverflow(isize, minInt(isize), 6, maxInt(isize) - 5, 1);
1120}
1121
1122test "@subWithOverflow > 64 bits" {
1123    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1124    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1125    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1126    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; // TODO
1127
1128    try testSubWithOverflow(u65, 4, 105, maxInt(u65) - 100, 1);
1129    try testSubWithOverflow(u65, 1000, 100, 900, 0);
1130    try testSubWithOverflow(u65, maxInt(u65), maxInt(u65), 0, 0);
1131    try testSubWithOverflow(u65, maxInt(u65) - 1, maxInt(u65), maxInt(u65), 1);
1132    try testSubWithOverflow(u65, maxInt(u65), maxInt(u65) - 1, 1, 0);
1133
1134    try testSubWithOverflow(u128, 4, 105, maxInt(u128) - 100, 1);
1135    try testSubWithOverflow(u128, 1000, 100, 900, 0);
1136    try testSubWithOverflow(u128, maxInt(u128), maxInt(u128), 0, 0);
1137    try testSubWithOverflow(u128, maxInt(u128) - 1, maxInt(u128), maxInt(u128), 1);
1138    try testSubWithOverflow(u128, maxInt(u128), maxInt(u128) - 1, 1, 0);
1139
1140    try testSubWithOverflow(i65, 4, 105, -101, 0);
1141    try testSubWithOverflow(i65, 1000, 100, 900, 0);
1142    try testSubWithOverflow(i65, maxInt(i65), maxInt(i65), 0, 0);
1143    try testSubWithOverflow(i65, minInt(i65), minInt(i65), 0, 0);
1144    try testSubWithOverflow(i65, maxInt(i65) - 1, maxInt(i65), -1, 0);
1145    try testSubWithOverflow(i65, maxInt(i65), maxInt(i65) - 1, 1, 0);
1146    try testSubWithOverflow(i65, minInt(i65), 1, maxInt(i65), 1);
1147    try testSubWithOverflow(i65, maxInt(i65), minInt(i65), -1, 1);
1148    try testSubWithOverflow(i65, minInt(i65), maxInt(i65), 1, 1);
1149    try testSubWithOverflow(i65, maxInt(i65), -2, minInt(i65) + 1, 1);
1150
1151    try testSubWithOverflow(i128, 4, 105, -101, 0);
1152    try testSubWithOverflow(i128, 1000, 100, 900, 0);
1153    try testSubWithOverflow(i128, maxInt(i128), maxInt(i128), 0, 0);
1154    try testSubWithOverflow(i128, minInt(i128), minInt(i128), 0, 0);
1155    try testSubWithOverflow(i128, maxInt(i128) - 1, maxInt(i128), -1, 0);
1156    try testSubWithOverflow(i128, maxInt(i128), maxInt(i128) - 1, 1, 0);
1157    try testSubWithOverflow(i128, minInt(i128), 1, maxInt(i128), 1);
1158    try testSubWithOverflow(i128, maxInt(i128), minInt(i128), -1, 1);
1159    try testSubWithOverflow(i128, minInt(i128), maxInt(i128), 1, 1);
1160    try testSubWithOverflow(i128, maxInt(i128), -2, minInt(i128) + 1, 1);
1161}
1162
1163fn testShlWithOverflow(comptime T: type, a: T, b: math.Log2Int(T), shl: T, bit: u1) !void {
1164    const ov = @shlWithOverflow(a, b);
1165    try expect(ov[0] == shl);
1166    try expect(ov[1] == bit);
1167}
1168
1169test "@shlWithOverflow" {
1170    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1171    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1172    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1173    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1174
1175    try testShlWithOverflow(u4, 2, 1, 4, 0);
1176    try testShlWithOverflow(u4, 2, 3, 0, 1);
1177
1178    try testShlWithOverflow(i9, 127, 1, 254, 0);
1179    try testShlWithOverflow(i9, 127, 2, -4, 1);
1180
1181    try testShlWithOverflow(u16, 0b0010111111111111, 3, 0b0111111111111000, 1);
1182    try testShlWithOverflow(u16, 0b0010111111111111, 2, 0b1011111111111100, 0);
1183
1184    try testShlWithOverflow(u16, 0b0000_0000_0000_0011, 15, 0b1000_0000_0000_0000, 1);
1185    try testShlWithOverflow(u16, 0b0000_0000_0000_0011, 14, 0b1100_0000_0000_0000, 0);
1186}
1187
1188test "@shlWithOverflow > 64 bits" {
1189    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1190    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1191    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1192    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1193
1194    try testShlWithOverflow(u65, 0x0_0100_0000_0000_0000, 7, 0x0_8000_0000_0000_0000, 0);
1195    try testShlWithOverflow(u65, 0x0_0100_0000_0000_0000, 8, 0x1_0000_0000_0000_0000, 0);
1196    try testShlWithOverflow(u65, 0x0_0100_0000_0000_0000, 9, 0, 1);
1197    try testShlWithOverflow(u65, 0x0_0100_0000_0000_0000, 10, 0, 1);
1198
1199    try testShlWithOverflow(u128, 0x0100_0000_0000_0000_0000000000000000, 6, 0x4000_0000_0000_0000_0000000000000000, 0);
1200    try testShlWithOverflow(u128, 0x0100_0000_0000_0000_0000000000000000, 7, 0x8000_0000_0000_0000_0000000000000000, 0);
1201    try testShlWithOverflow(u128, 0x0100_0000_0000_0000_0000000000000000, 8, 0, 1);
1202    try testShlWithOverflow(u128, 0x0100_0000_0000_0000_0000000000000000, 9, 0, 1);
1203
1204    try testShlWithOverflow(i65, 0x0_0100_0000_0000_0000, 7, 0x0_8000_0000_0000_0000, 0);
1205    try testShlWithOverflow(i65, 0x0_0100_0000_0000_0000, 8, minInt(i65), 1);
1206    try testShlWithOverflow(i65, 0x0_0100_0000_0000_0000, 9, 0, 1);
1207    try testShlWithOverflow(i65, 0x0_0100_0000_0000_0000, 10, 0, 1);
1208
1209    try testShlWithOverflow(i128, 0x0100_0000_0000_0000_0000000000000000, 6, 0x4000_0000_0000_0000_0000000000000000, 0);
1210    try testShlWithOverflow(i128, 0x0100_0000_0000_0000_0000000000000000, 7, minInt(i128), 1);
1211    try testShlWithOverflow(i128, 0x0100_0000_0000_0000_0000000000000000, 8, 0, 1);
1212    try testShlWithOverflow(i128, 0x0100_0000_0000_0000_0000000000000000, 9, 0, 1);
1213}
1214
1215test "overflow arithmetic with u0 values" {
1216    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1217
1218    {
1219        var a: u0 = 0;
1220        _ = &a;
1221        const ov = @addWithOverflow(a, 0);
1222        try expect(ov[1] == 0);
1223        try expect(ov[1] == 0);
1224    }
1225    {
1226        var a: u0 = 0;
1227        _ = &a;
1228        const ov = @subWithOverflow(a, 0);
1229        try expect(ov[1] == 0);
1230        try expect(ov[1] == 0);
1231    }
1232    {
1233        var a: u0 = 0;
1234        _ = &a;
1235        const ov = @mulWithOverflow(a, 0);
1236        try expect(ov[1] == 0);
1237        try expect(ov[1] == 0);
1238    }
1239    {
1240        var a: u0 = 0;
1241        _ = &a;
1242        const ov = @shlWithOverflow(a, 0);
1243        try expect(ov[1] == 0);
1244        try expect(ov[1] == 0);
1245    }
1246}
1247
1248test "allow signed integer division/remainder when values are comptime-known and positive or exact" {
1249    try expect(5 / 3 == 1);
1250    try expect(-5 / -3 == 1);
1251    try expect(-6 / 3 == -2);
1252
1253    try expect(5 % 3 == 2);
1254    try expect(-6 % 3 == 0);
1255}
1256
1257test "quad hex float literal parsing accurate" {
1258    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1259    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1260    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1261    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1262
1263    const a: f128 = 0x1.1111222233334444555566667777p+0;
1264
1265    // implied 1 is dropped, with an exponent of 0 (0x3fff) after biasing.
1266    const expected: u128 = 0x3fff1111222233334444555566667777;
1267    try expect(@as(u128, @bitCast(a)) == expected);
1268
1269    // non-normalized
1270    const b: f128 = 0x11.111222233334444555566667777p-4;
1271    try expect(@as(u128, @bitCast(b)) == expected);
1272
1273    const S = struct {
1274        fn doTheTest() !void {
1275            {
1276                var f: f128 = 0x1.2eab345678439abcdefea56782346p+5;
1277                _ = &f;
1278                try expect(@as(u128, @bitCast(f)) == 0x40042eab345678439abcdefea5678234);
1279            }
1280            {
1281                var f: f128 = 0x1.edcb34a235253948765432134674fp-1;
1282                _ = &f;
1283                try expect(@as(u128, @bitCast(f)) == 0x3ffeedcb34a235253948765432134675); // round-to-even
1284            }
1285            {
1286                var f: f128 = 0x1.353e45674d89abacc3a2ebf3ff4ffp-50;
1287                _ = &f;
1288                try expect(@as(u128, @bitCast(f)) == 0x3fcd353e45674d89abacc3a2ebf3ff50);
1289            }
1290            {
1291                var f: f128 = 0x1.ed8764648369535adf4be3214567fp-9;
1292                _ = &f;
1293                try expect(@as(u128, @bitCast(f)) == 0x3ff6ed8764648369535adf4be3214568);
1294            }
1295            const exp2ft = [_]f64{
1296                0x1.6a09e667f3bcdp-1,
1297                0x1.7a11473eb0187p-1,
1298                0x1.8ace5422aa0dbp-1,
1299                0x1.9c49182a3f090p-1,
1300                0x1.ae89f995ad3adp-1,
1301                0x1.c199bdd85529cp-1,
1302                0x1.d5818dcfba487p-1,
1303                0x1.ea4afa2a490dap-1,
1304                0x1.0000000000000p+0,
1305                0x1.0b5586cf9890fp+0,
1306                0x1.172b83c7d517bp+0,
1307                0x1.2387a6e756238p+0,
1308                0x1.306fe0a31b715p+0,
1309                0x1.3dea64c123422p+0,
1310                0x1.4bfdad5362a27p+0,
1311                0x1.5ab07dd485429p+0,
1312                0x1.8p23,
1313                0x1.62e430p-1,
1314                0x1.ebfbe0p-3,
1315                0x1.c6b348p-5,
1316                0x1.3b2c9cp-7,
1317                0x1.0p127,
1318                -0x1.0p-149,
1319            };
1320
1321            const answers = [_]u64{
1322                0x3fe6a09e667f3bcd,
1323                0x3fe7a11473eb0187,
1324                0x3fe8ace5422aa0db,
1325                0x3fe9c49182a3f090,
1326                0x3feae89f995ad3ad,
1327                0x3fec199bdd85529c,
1328                0x3fed5818dcfba487,
1329                0x3feea4afa2a490da,
1330                0x3ff0000000000000,
1331                0x3ff0b5586cf9890f,
1332                0x3ff172b83c7d517b,
1333                0x3ff2387a6e756238,
1334                0x3ff306fe0a31b715,
1335                0x3ff3dea64c123422,
1336                0x3ff4bfdad5362a27,
1337                0x3ff5ab07dd485429,
1338                0x4168000000000000,
1339                0x3fe62e4300000000,
1340                0x3fcebfbe00000000,
1341                0x3fac6b3480000000,
1342                0x3f83b2c9c0000000,
1343                0x47e0000000000000,
1344                0xb6a0000000000000,
1345            };
1346
1347            for (exp2ft, 0..) |x, i| {
1348                try expect(@as(u64, @bitCast(x)) == answers[i]);
1349            }
1350        }
1351    };
1352    try S.doTheTest();
1353    try comptime S.doTheTest();
1354}
1355
1356test "truncating shift left" {
1357    try testShlTrunc(maxInt(u16));
1358    try comptime testShlTrunc(maxInt(u16));
1359}
1360fn testShlTrunc(x: u16) !void {
1361    const shifted = x << 1;
1362    try expect(shifted == 65534);
1363}
1364
1365test "exact shift left" {
1366    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1367
1368    try testShlExact(0b00110101);
1369    try comptime testShlExact(0b00110101);
1370
1371    if (@shlExact(1, 1) != 2) @compileError("should be 2");
1372}
1373fn testShlExact(x: u8) !void {
1374    const shifted = @shlExact(x, 2);
1375    try expect(shifted == 0b11010100);
1376}
1377
1378test "exact shift right" {
1379    try testShrExact(0b10110100);
1380    try comptime testShrExact(0b10110100);
1381}
1382fn testShrExact(x: u8) !void {
1383    const shifted = @shrExact(x, 2);
1384    try expect(shifted == 0b00101101);
1385}
1386
1387test "shift left/right on u0 operand" {
1388    const S = struct {
1389        fn doTheTest() !void {
1390            var x: u0 = 0;
1391            var y: u0 = 0;
1392            _ = .{ &x, &y };
1393            try expectEqual(@as(u0, 0), x << 0);
1394            try expectEqual(@as(u0, 0), x >> 0);
1395            try expectEqual(@as(u0, 0), x << y);
1396            try expectEqual(@as(u0, 0), x >> y);
1397            try expectEqual(@as(u0, 0), @shlExact(x, 0));
1398            try expectEqual(@as(u0, 0), @shrExact(x, 0));
1399            try expectEqual(@as(u0, 0), @shlExact(x, y));
1400            try expectEqual(@as(u0, 0), @shrExact(x, y));
1401        }
1402    };
1403    try S.doTheTest();
1404    try comptime S.doTheTest();
1405}
1406
1407test "comptime float rem int" {
1408    comptime {
1409        const x = @as(f32, 1) % 2;
1410        try expect(x == 1.0);
1411    }
1412}
1413
1414test "remainder division" {
1415    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1416    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1417    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1418    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1419    if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1420    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1421
1422    if (builtin.zig_backend == .stage2_llvm and builtin.os.tag == .windows) {
1423        // https://github.com/ziglang/zig/issues/12602
1424        return error.SkipZigTest;
1425    }
1426
1427    if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;
1428
1429    try comptime remdiv(f16);
1430    try comptime remdiv(f32);
1431    try comptime remdiv(f64);
1432    try comptime remdiv(f80);
1433    try comptime remdiv(f128);
1434    try remdiv(f16);
1435    try remdiv(f32);
1436    try remdiv(f64);
1437    try remdiv(f80);
1438    try remdiv(f128);
1439}
1440
1441fn remdiv(comptime T: type) !void {
1442    try expect(@as(T, 1) == @as(T, 1) % @as(T, 2));
1443    try remdivOne(T, 1, 1, 2);
1444
1445    try expect(@as(T, 1) == @as(T, 7) % @as(T, 3));
1446    try remdivOne(T, 1, 7, 3);
1447}
1448
1449fn remdivOne(comptime T: type, a: T, b: T, c: T) !void {
1450    try expect(a == @rem(b, c));
1451    try expect(a == @mod(b, c));
1452}
1453
1454test "float remainder division using @rem" {
1455    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1456    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1457    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1458    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1459
1460    try comptime frem(f16);
1461    try comptime frem(f32);
1462    try comptime frem(f64);
1463    try comptime frem(f80);
1464    try comptime frem(f128);
1465    try frem(f16);
1466    try frem(f32);
1467    try frem(f64);
1468    try frem(f80);
1469    try frem(f128);
1470}
1471
1472fn frem(comptime T: type) !void {
1473    const epsilon = switch (T) {
1474        f16 => 1.0,
1475        f32 => 0.001,
1476        f64 => 0.00001,
1477        f80 => 0.000001,
1478        f128 => 0.0000001,
1479        else => unreachable,
1480    };
1481
1482    try fremOne(T, 6.9, 4.0, 2.9, epsilon);
1483    try fremOne(T, -6.9, 4.0, -2.9, epsilon);
1484    try fremOne(T, -5.0, 3.0, -2.0, epsilon);
1485    try fremOne(T, 3.0, 2.0, 1.0, epsilon);
1486    try fremOne(T, 1.0, 2.0, 1.0, epsilon);
1487    try fremOne(T, 0.0, 1.0, 0.0, epsilon);
1488    try fremOne(T, -0.0, 1.0, -0.0, epsilon);
1489}
1490
1491fn fremOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void {
1492    try expect(@abs(@rem(a, b) - c) < epsilon);
1493}
1494
1495test "float modulo division using @mod" {
1496    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1497    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1498    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1499    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1500    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1501
1502    if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;
1503
1504    try comptime fmod(f16);
1505    try comptime fmod(f32);
1506    try comptime fmod(f64);
1507    try comptime fmod(f80);
1508    try comptime fmod(f128);
1509    try fmod(f16);
1510    try fmod(f32);
1511    try fmod(f64);
1512    try fmod(f80);
1513    try fmod(f128);
1514}
1515
1516fn fmod(comptime T: type) !void {
1517    const epsilon = switch (T) {
1518        f16 => 1.0,
1519        f32 => 0.001,
1520        f64 => 0.00001,
1521        f80 => 0.000001,
1522        f128 => 0.0000001,
1523        else => unreachable,
1524    };
1525
1526    try fmodOne(T, 6.9, 4.0, 2.9, epsilon);
1527    try fmodOne(T, -6.9, 4.0, 1.1, epsilon);
1528    try fmodOne(T, -5.0, 3.0, 1.0, epsilon);
1529    try fmodOne(T, 3.0, 2.0, 1.0, epsilon);
1530    try fmodOne(T, 1.0, 2.0, 1.0, epsilon);
1531    try fmodOne(T, 0.0, 1.0, 0.0, epsilon);
1532    try fmodOne(T, -0.0, 1.0, -0.0, epsilon);
1533}
1534
1535fn fmodOne(comptime T: type, a: T, b: T, c: T, epsilon: T) !void {
1536    try expect(@abs(@mod(@as(T, a), @as(T, b)) - @as(T, c)) < epsilon);
1537}
1538
1539test "@round f16" {
1540    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1541    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1542    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1543
1544    try testRound(f16, 12.0);
1545    try comptime testRound(f16, 12.0);
1546}
1547
1548test "@round f32/f64" {
1549    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1550    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1551    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1552
1553    try testRound(f64, 12.0);
1554    try comptime testRound(f64, 12.0);
1555    try testRound(f32, 12.0);
1556    try comptime testRound(f32, 12.0);
1557
1558    const x = 14.0;
1559    const y = x + 0.4;
1560    const z = @round(y);
1561    comptime assert(x == z);
1562}
1563
1564test "@round f80" {
1565    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1566    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1567    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1568    if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1569    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1570
1571    try testRound(f80, 12.0);
1572    try comptime testRound(f80, 12.0);
1573}
1574
1575test "@round f128" {
1576    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1577    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1578    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1579    if (builtin.zig_backend == .stage2_c and builtin.cpu.arch.isArm()) return error.SkipZigTest;
1580    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1581
1582    try testRound(f128, 12.0);
1583    try comptime testRound(f128, 12.0);
1584}
1585
1586fn testRound(comptime T: type, x: T) !void {
1587    const y = x - 0.5;
1588    const z = @round(y);
1589    try expect(x == z);
1590}
1591
1592test "vector integer addition" {
1593    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1594    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1595    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1596    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1597    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1598    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1599
1600    const S = struct {
1601        fn doTheTest() !void {
1602            var a: @Vector(4, i32) = [_]i32{ 1, 2, 3, 4 };
1603            var b: @Vector(4, i32) = [_]i32{ 5, 6, 7, 8 };
1604            _ = .{ &a, &b };
1605            const result = a + b;
1606            var result_array: [4]i32 = result;
1607            const expected = [_]i32{ 6, 8, 10, 12 };
1608            try expectEqualSlices(i32, &expected, &result_array);
1609        }
1610    };
1611    try S.doTheTest();
1612    try comptime S.doTheTest();
1613}
1614
1615test "NaN comparison" {
1616    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1617    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1618    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1619    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1620    if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
1621
1622    try testNanEqNan(f16);
1623    try testNanEqNan(f32);
1624    try testNanEqNan(f64);
1625    try testNanEqNan(f128);
1626    try comptime testNanEqNan(f16);
1627    try comptime testNanEqNan(f32);
1628    try comptime testNanEqNan(f64);
1629    try comptime testNanEqNan(f128);
1630}
1631
1632test "NaN comparison f80" {
1633    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1634    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1635    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1636    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1637
1638    try testNanEqNan(f80);
1639    try comptime testNanEqNan(f80);
1640}
1641
1642fn testNanEqNan(comptime F: type) !void {
1643    var nan1 = math.nan(F);
1644    var nan2 = math.nan(F);
1645    _ = .{ &nan1, &nan2 };
1646    try expect(nan1 != nan2);
1647    try expect(!(nan1 == nan2));
1648    try expect(!(nan1 > nan2));
1649    try expect(!(nan1 >= nan2));
1650    try expect(!(nan1 < nan2));
1651    try expect(!(nan1 <= nan2));
1652}
1653
1654test "vector comparison" {
1655    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1656    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1657    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1658    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1659    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1660    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1661
1662    const S = struct {
1663        fn doTheTest() !void {
1664            var a: @Vector(6, i32) = [_]i32{ 1, 3, -1, 5, 7, 9 };
1665            var b: @Vector(6, i32) = [_]i32{ -1, 3, 0, 6, 10, -10 };
1666            _ = .{ &a, &b };
1667            try expect(mem.eql(bool, &@as([6]bool, a < b), &[_]bool{ false, false, true, true, true, false }));
1668            try expect(mem.eql(bool, &@as([6]bool, a <= b), &[_]bool{ false, true, true, true, true, false }));
1669            try expect(mem.eql(bool, &@as([6]bool, a == b), &[_]bool{ false, true, false, false, false, false }));
1670            try expect(mem.eql(bool, &@as([6]bool, a != b), &[_]bool{ true, false, true, true, true, true }));
1671            try expect(mem.eql(bool, &@as([6]bool, a > b), &[_]bool{ true, false, false, false, false, true }));
1672            try expect(mem.eql(bool, &@as([6]bool, a >= b), &[_]bool{ true, true, false, false, false, true }));
1673        }
1674    };
1675    try S.doTheTest();
1676    try comptime S.doTheTest();
1677}
1678
1679test "compare undefined literal with comptime_int" {
1680    var x = undefined == 1;
1681    // x is now undefined with type bool
1682    x = true;
1683    try expect(x);
1684}
1685
1686test "signed zeros are represented properly" {
1687    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1688    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1689    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1690    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1691
1692    const S = struct {
1693        fn doTheTest() !void {
1694            try testOne(f16);
1695            try testOne(f32);
1696            try testOne(f64);
1697            try testOne(f80);
1698            try testOne(f128);
1699            try testOne(c_longdouble);
1700        }
1701
1702        fn testOne(comptime T: type) !void {
1703            const ST = std.meta.Int(.unsigned, @typeInfo(T).float.bits);
1704            var as_fp_val = -@as(T, 0.0);
1705            _ = &as_fp_val;
1706            const as_uint_val: ST = @bitCast(as_fp_val);
1707            // Ensure the sign bit is set.
1708            try expect(as_uint_val >> (@typeInfo(T).float.bits - 1) == 1);
1709        }
1710    };
1711
1712    try S.doTheTest();
1713    try comptime S.doTheTest();
1714}
1715
1716test "absFloat" {
1717    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1718    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1719
1720    try testAbsFloat();
1721    try comptime testAbsFloat();
1722}
1723fn testAbsFloat() !void {
1724    try testAbsFloatOne(-10.05, 10.05);
1725    try testAbsFloatOne(10.05, 10.05);
1726}
1727fn testAbsFloatOne(in: f32, out: f32) !void {
1728    try expect(@abs(@as(f32, in)) == @as(f32, out));
1729}
1730
1731test "mod lazy values" {
1732    {
1733        const X = struct { x: u32 };
1734        const x = @sizeOf(X);
1735        const y = 1 % x;
1736        _ = y;
1737    }
1738    {
1739        const X = struct { x: u32 };
1740        const x = @sizeOf(X);
1741        const y = x % 1;
1742        _ = y;
1743    }
1744}
1745
1746test "@clz works on both vector and scalar inputs" {
1747    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1748    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1749    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1750    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1751    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1752    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1753
1754    var x: u32 = 0x1;
1755    _ = &x;
1756    var y: @Vector(4, u32) = [_]u32{ 0x1, 0x1, 0x1, 0x1 };
1757    _ = &y;
1758    const a = @clz(x);
1759    const b = @clz(y);
1760    try std.testing.expectEqual(@as(u6, 31), a);
1761    try std.testing.expectEqual([_]u6{ 31, 31, 31, 31 }, b);
1762}
1763
1764test "runtime comparison to NaN is comptime-known" {
1765    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1766    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1767    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1768    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1769    if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
1770
1771    const S = struct {
1772        fn doTheTest(comptime F: type, x: F) void {
1773            const nan = math.nan(F);
1774            if (!(nan != x)) comptime unreachable;
1775            if (nan == x) comptime unreachable;
1776            if (nan > x) comptime unreachable;
1777            if (nan < x) comptime unreachable;
1778            if (nan >= x) comptime unreachable;
1779            if (nan <= x) comptime unreachable;
1780        }
1781    };
1782
1783    S.doTheTest(f16, 123.0);
1784    S.doTheTest(f32, 123.0);
1785    S.doTheTest(f64, 123.0);
1786    S.doTheTest(f128, 123.0);
1787    comptime S.doTheTest(f16, 123.0);
1788    comptime S.doTheTest(f32, 123.0);
1789    comptime S.doTheTest(f64, 123.0);
1790    comptime S.doTheTest(f128, 123.0);
1791}
1792
1793test "runtime int comparison to inf is comptime-known" {
1794    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1795    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1796    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1797    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1798    if (builtin.cpu.arch.isArm() and builtin.target.abi.float() == .soft) return error.SkipZigTest; // https://github.com/ziglang/zig/issues/21234
1799
1800    const S = struct {
1801        fn doTheTest(comptime F: type, x: u32) void {
1802            const inf = math.inf(F);
1803            if (!(inf != x)) comptime unreachable;
1804            if (inf == x) comptime unreachable;
1805            if (x > inf) comptime unreachable;
1806            if (x >= inf) comptime unreachable;
1807            if (!(x < inf)) comptime unreachable;
1808            if (!(x <= inf)) comptime unreachable;
1809        }
1810    };
1811
1812    S.doTheTest(f16, 123);
1813    S.doTheTest(f32, 123);
1814    S.doTheTest(f64, 123);
1815    S.doTheTest(f128, 123);
1816    comptime S.doTheTest(f16, 123);
1817    comptime S.doTheTest(f32, 123);
1818    comptime S.doTheTest(f64, 123);
1819    comptime S.doTheTest(f128, 123);
1820}
1821
1822test "float divide by zero" {
1823    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1824    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1825    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1826    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1827    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1828
1829    if (builtin.zig_backend == .stage2_x86_64 and builtin.object_format == .coff and builtin.abi != .gnu) return error.SkipZigTest;
1830
1831    const S = struct {
1832        fn doTheTest(comptime F: type, zero: F, one: F) !void {
1833            try expect(math.isPositiveInf(@divTrunc(one, zero)));
1834            try expect(math.isPositiveInf(@divFloor(one, zero)));
1835
1836            try expect(math.isNan(@rem(one, zero)));
1837            try expect(math.isNan(@mod(one, zero)));
1838        }
1839    };
1840
1841    try S.doTheTest(f16, 0, 1);
1842    comptime S.doTheTest(f16, 0, 1) catch unreachable;
1843
1844    try S.doTheTest(f32, 0, 1);
1845    comptime S.doTheTest(f32, 0, 1) catch unreachable;
1846
1847    try S.doTheTest(f64, 0, 1);
1848    comptime S.doTheTest(f64, 0, 1) catch unreachable;
1849
1850    try S.doTheTest(f80, 0, 1);
1851    comptime S.doTheTest(f80, 0, 1) catch unreachable;
1852
1853    try S.doTheTest(f128, 0, 1);
1854    comptime S.doTheTest(f128, 0, 1) catch unreachable;
1855}
1856
1857test "partially-runtime integer vector division would be illegal if vector elements were reordered" {
1858    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1859    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1860    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1861    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1862    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1863    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1864    if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .hexagon) return error.SkipZigTest;
1865
1866    var lhs: @Vector(2, i8) = .{ -128, 5 };
1867    const rhs: @Vector(2, i8) = .{ 1, -1 };
1868
1869    const expected: @Vector(2, i8) = .{ -128, -5 };
1870
1871    lhs = lhs; // suppress error
1872
1873    const trunc = @divTrunc(lhs, rhs);
1874    try expect(trunc[0] == expected[0]);
1875    try expect(trunc[1] == expected[1]);
1876
1877    const floor = @divFloor(lhs, rhs);
1878    try expect(floor[0] == expected[0]);
1879    try expect(floor[1] == expected[1]);
1880
1881    const exact = @divExact(lhs, rhs);
1882    try expect(exact[0] == expected[0]);
1883    try expect(exact[1] == expected[1]);
1884}
1885
1886test "float vector division of comptime zero by runtime nan is nan" {
1887    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1888    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1889    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1890    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1891    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1892    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1893
1894    const ct_zero: @Vector(1, f32) = .{0};
1895    var rt_nan: @Vector(1, f32) = .{math.nan(f32)};
1896
1897    rt_nan = rt_nan; // suppress error
1898
1899    try expect(math.isNan((@divTrunc(ct_zero, rt_nan))[0]));
1900    try expect(math.isNan((@divFloor(ct_zero, rt_nan))[0]));
1901    try expect(math.isNan((ct_zero / rt_nan)[0]));
1902}
1903
1904test "float vector multiplication of comptime zero by runtime nan is nan" {
1905    if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
1906    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1907    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1908    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1909    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1910    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1911
1912    const ct_zero: @Vector(1, f32) = .{0};
1913    var rt_nan: @Vector(1, f32) = .{math.nan(f32)};
1914
1915    rt_nan = rt_nan; // suppress error
1916
1917    try expect(math.isNan((ct_zero * rt_nan)[0]));
1918    try expect(math.isNan((rt_nan * ct_zero)[0]));
1919}
1920
1921test "comptime float vector division of zero by nan is nan" {
1922    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1923    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1924    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1925    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1926    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1927
1928    const ct_zero: @Vector(1, f32) = .{0};
1929    const ct_nan: @Vector(1, f32) = .{math.nan(f32)};
1930
1931    comptime assert(math.isNan((@divTrunc(ct_zero, ct_nan))[0]));
1932    comptime assert(math.isNan((@divFloor(ct_zero, ct_nan))[0]));
1933    comptime assert(math.isNan((ct_zero / ct_nan)[0]));
1934}
1935
1936test "comptime float vector multiplication of zero by nan is nan" {
1937    if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
1938    if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
1939    if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
1940    if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
1941    if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
1942
1943    const ct_zero: @Vector(1, f32) = .{0};
1944    const ct_nan: @Vector(1, f32) = .{math.nan(f32)};
1945
1946    comptime assert(math.isNan((ct_zero * ct_nan)[0]));
1947    comptime assert(math.isNan((ct_nan * ct_zero)[0]));
1948}