> Hi,
>
>
> Yet another idea is to use original binary format: divide the
> value into sign, exponent and mantissa, then encode them
> severally.
>
[ patch follows ]

The DBL_DIG patch makes the problem less common, but does not solve it;

[[1,2,3,4], [81, 2, 118, 3146]].each { |w,x,y,z|
a = (x.to_f + y.to_f / z.to_f) * Math.exp(w.to_f / (x.to_f + y.to_f / z.to_f))
ma = Marshal.dump(a)
if a == b
puts "Everything is working fine for #{a}"
else
puts "PROBLEM: a is #{a}, b is #{b}, and ma is #{ma.dump}"
end
}

Produces

Everything is working fine for 3.95601527633861
PROBLEM: a is 3.7517675036461267e+17, b is 3.7517675036461261e+17,
and ma is "\004\010f\e3.7517675036461267e+17"

The problem remains that certain numbers that are
exactly representable in binary are not exactly
representable in decimal without more precise rounding
rules than sprintf gives us.  I think that your other
suggestion about dividing into sign, mantissa, and
exponent would work, but I am not sure I see the
advantage, as it seems it would be more complex and
perhaps larger than just saving the least significant
few bits of the mantissa.