From: Mauricio Fernandez Date: 2006-05-18T07:49:34+09:00 Subject: Re: greatest float smaller than 1.0? On Thu, May 18, 2006 at 06:52:18AM +0900, Joel VanderWerf wrote: > Joel VanderWerf wrote: > > polypus wrote: > >> how do i get the greatest float smaller than 1.0? > >> > >> thanks > >> > > > > Something like this maybe? > > > > irb(main):006:0> [0.9999999999999999].pack "G" > > => "?\357\377\377\377\377\377\377" > > > > (that was just to find out what floats look like in memory, big-endian). > > > > irb(main):012:0> x = ("?\357" + "\377"*100).unpack "G" > > => [1.0] > > irb(main):013:0> "%30f" % x > > => "0.999999999999999888977697537484" > > > > Dunno if that's safe on all platforms... > > That was completely wrong, please ignore. > > irb(main):059:0> y = 1e-305 > => 1.0e-305 > irb(main):060:0> [y].pack "G" > => "\000\234\026\305\305%5t" > irb(main):061:0> [y].pack("G").unpack("G") > => [1.0e-305] > > It's the exponent that needs to be chosen, not just the mantissa. > > Still, it leaves the question open why Float::EPSILON is nowhere near > this exponent. oops subtraction == funny x = 1.0 - Float::EPSILON/2 # => 1.0 "%.30f" % x # => "0.999999999999999888977697537484" EPSILON is a bound for the relative error between a real and its floating point representation, not the smallest (absolute value) representable value. It's clearer with addition: x = 1.0 + Float::EPSILON # => 1.0 "%.30f" % x # => "1.000000000000000222044604925031" x = 1.0 + Float::EPSILON/2 # => 1.0 "%.30f" % x # => "1.000000000000000000000000000000" -- Mauricio Fernandez - http://eigenclass.org - singular Ruby