The algorithm looks sound, and it worked it out "on paper" and it seems right. Here are my worked out notes for FromRaw(2265950765) * FromRaw(17179869183)
(0.52758277510292828083038330078125 * 3.99999999976716935634613037109375 = 2.11033110017888247966766357421875)
x1 = 2265950765
y1 = 17179869183
xlow = 2265950765
xhigh = 0
ylow = 4294967295
yhigh = 3
lowlow = 9732184427755230675
lowhigh = 6797852295
highlow = 0
highhigh = 0
loResult = 2265950764
midResult1 = 6797852295
midResult2 = 0
hiResult = 0
finalResult = 9063803059
Now here's what I suspect is happening: lowlow
needs to be a ulong
for the result to come out right, but I think that what you're getting is a signed value. Interpreted as signed, lowlow
ends up being -8714559645954320941 (too low by 2^64), loResult
ends up being -2029016532 (too low by 2^32), finalResult
ends up being 4768835763
(also too low by 2^32), and the resulting value is then 1.11033110017888247966766357421875 which is exactly 1 less than you expect.
In general your values should be treated as having a signed "upper half" and an unsigned "lower half". highhigh
is signed * signed = signed; lowhigh
and highlow
are signed * unsigned = signed; but lowlow
is unsigned * unsigned = unsigned.