Difference (from prior major revision)
(minor diff, author diff)
Changed: 7c7
Changed: 36c36
if lo ~= 0 then x = lo; p[i] = hi; i = i + 1 end
|
if lo ~= 0 then p[i] = x; x = lo; i = i + 1 end
|
Removed: 39d38
Added: 40a40
Changed: 45c45,46
local ok, prev = true, {unpack(p, 1, p[1])}
|
local n, overlap = p[1], false local prev = {unpack(p, 1, n)}
|
Changed: 47,50c48,50
if p[1] == 2 then return p[2] end if p[1] == 3 then return p[2] + p[3] end for i = 1, p[1] do if p[i] ~= prev[i] then ok = false; break end
|
if n <= 3 then return p[2] end for i = 1, n do if p[i] ~= prev[i] then overlap = true; break end
|
Changed: 52c52
Accurate floating point summation. Like Python's fsum.
This version collect partial sums in reverse order, with each
entry (except last) used up all 53 bits.
With less partials to sum, it's speed is 2X of my old version
(see FloatSum)
To see my C/C++ versions (see https://github.com/achan001/fsum)
local function fsum(...)
local p, abs = {1}, math.abs
local function fadd(x)
local p, i = p, 2
for j = 2, p[1] do
local y = p[j]
if abs(x) > abs(y) then x, y = y, x end
local hi = x + y
local lo = x - (hi - y)
x = hi
if lo ~= 0 then p[i] = x; x = lo; i = i + 1 end
end
if x ~= x then p[1] = 2 return end
p[1] = i
p[i] = x
end
local function ftotal(clear)
if clear then p[1] = 1 end
repeat
local n, overlap = p[1], false
local prev = {unpack(p, 1, n)}
fadd(0)
if n <= 3 then return p[2] end
for i = 1, n do
if p[i] ~= prev[i] then overlap = true; break end
end
until not overlap
local x, lo, err = unpack(p, 2, 4)
if (lo < 0) == (err < 0) then
lo = lo * 2
local hi = x + lo
if lo == hi - x then x = hi end
end
return x
end
if select('#', ...) == 0 then return fadd, ftotal end
for i = 1, select('#', ...) do fadd(select(i, ...)) end
return ftotal()
end
if select(1, ...) ~= 'fsum' then
local read, fadd, ftotal = io.read, fsum()
io.input(select(1, ...))
pcall(function() while true do fadd(read('*n')) end end)
print(ftotal())
end
return fsum
RecentChanges · preferences
edit · history
Last edited June 24, 2018 3:29 am GMT (diff)