Compute a*b exactly, returning the exact result in a struct dd. We assume that both a and b are normalized, so no underflow or overflow will occur. The current rounding mode must be round-to-nearest.
fn dd_mul128(a: f128, b: f128) dd128
fn dd_mul128(a: f128, b: f128) dd128 {
var ret: dd128 = undefined;
const split: f128 = 0x1.0p57 + 1.0;
var p = a * split;
var ha = a - p;
ha += p;
const la = a - ha;
p = b * split;
var hb = b - p;
hb += p;
const lb = b - hb;
p = ha * hb;
const q = ha * lb + la * hb;
ret.hi = p + q;
ret.lo = p - ret.hi + q + la * lb;
return ret;
}