| author | |
| committer | |
| log | 85d188537538cdb7929ac05d7960d6b724676d7f |
| tree | 7081624832f2880ad46a33dad7d72c6f24b95f3a |
| parent | 64b2cf776c4efa92f6be180c25ff13d49b495cbf |
2 files changed, 12 insertions(+), 8 deletions(-)
std/math.zig+11| ... | ... | @@ -806,3 +806,14 @@ test "max value type" { |
| 806 | 806 | const x: u32 = maxInt(i32); |
| 807 | 807 | testing.expect(x == 2147483647); |
| 808 | 808 | } |
| 809 | ||
| 810 | pub fn mulWide(comptime T: type, a: T, b: T) @IntType(T.is_signed, T.bit_count * 2) { | |
| 811 | const ResultInt = @IntType(T.is_signed, T.bit_count * 2); | |
| 812 | return ResultInt(a) * ResultInt(b); | |
| 813 | } | |
| 814 | ||
| 815 | test "math.wideMul" { | |
| 816 | testing.expect(wideMul(u8, 5, 5) == 25); | |
| 817 | testing.expect(wideMul(i8, 5, -5) == -25); | |
| 818 | testing.expect(wideMul(u8, 100, 100) == 10000); | |
| 819 | } |
std/math/big/int.zig+1-8| ... | ... | @@ -705,14 +705,7 @@ pub const Int = struct { |
| 705 | 705 | const c1: Limb = @boolToInt(@addWithOverflow(Limb, a, carry.*, &r1)); |
| 706 | 706 | |
| 707 | 707 | // r2 = b * c |
| 708 | // | |
| 709 | // We still use a DoubleLimb here since the @mulWithOverflow builtin does not | |
| 710 | // return the carry and lower bits separately so we would need to perform this | |
| 711 | // anyway to get the carry bits. The branch on the overflow case costs more than | |
| 712 | // just computing them unconditionally and splitting. | |
| 713 | // | |
| 714 | // This could be a single x86 mul instruction, which stores the carry/lower in rdx:rax. | |
| 715 | const bc = DoubleLimb(b) * DoubleLimb(c); | |
| 708 | const bc = DoubleLimb(math.mulWide(Limb, b, c)); | |
| 716 | 709 | const r2 = @truncate(Limb, bc); |
| 717 | 710 | const c2 = @truncate(Limb, bc >> Limb.bit_count); |
| 718 | 711 |