https://issues.dlang.org/show_bug.cgi?id=12958

safety0ff.bugz <[email protected]> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |[email protected]

--- Comment #1 from safety0ff.bugz <[email protected]> ---
I tried this, I tried checking the partial results individually and combining
then checking. The latter worked better (though ldc still didn't combine the
mul's)

Attached is the code with the additional unit tests (tests already in
checkedint are ommitted.)

// CODE
ulong mulu(ulong x, ulong y, ref bool overflow)
{
    uint xlo = cast(uint)x;
    uint xhi = cast(uint)(x>>32);
    uint ylo = cast(uint)y;
    uint yhi = cast(uint)(y>>32);
    ulong xlo_ylo = cast(ulong)xlo * ylo;
    ulong xhi_ylo = cast(ulong)xhi * ylo;
    ulong xlo_yhi = cast(ulong)xlo * yhi;
    ulong xhi_yhi = cast(ulong)xhi * yhi;
    ulong res_lo = (xhi_ylo<<32) + (xlo_yhi<<32) + xlo_ylo;
    // '|' or '||' would suffice
    ulong res_hi = xhi_yhi + (xhi_ylo>>32) + (xlo_yhi>>32);
    if (res_hi)
        overflow = true;
    return res_lo;
}

unittest
{
    bool overflow;
    assert(mulu(1uL<<32,1uL<<32, overflow) == 0);
    assert(overflow);
    overflow = false;
    assert(mulu((1uL<<32) +1,1uL<<32, overflow) == 1uL<<32);
    assert(overflow);
    overflow = false;
    assert(mulu((1uL<<32) +1,(1uL<<32)+1, overflow) == 1+(2uL<<32));
    assert(overflow);
    overflow = false;
}

--

Reply via email to