how do i get the greatest float smaller than 1.0? thanks

on 2006-05-17 22:54

on 2006-05-17 23:08

polypus wrote: > how do i get the greatest float smaller than 1.0? > > thanks > > 0.999999999999999 ? irb(main):001:0> 0.99999999999 => 0.99999999999 irb(main):002:0> 0.99999999999999 => 0.99999999999999 irb(main):003:0> 0.999999999999999 => 0.999999999999999 irb(main):004:0> 0.9999999999999999 => 1.0 irb(main):005:0> 0.9999999999999991 => 0.999999999999999 irb(main):006:0> 0.99999999999999912 => 0.999999999999999 irb(main):007:0> 0.9999999999999992 => 0.999999999999999 irb(main):008:0> 0.9999999999999993 => 0.999999999999999 irb(main):009:0> 0.9999999999999994 => 0.999999999999999 irb(main):010:0> 0.9999999999999995 => 0.999999999999999 irb(main):011:0> 0.9999999999999996 => 1.0 Dunno. -Justin

on 2006-05-17 23:12

I'd expect it to be platform-dependent. I also think this is one of those questions that are better off not asked :-) so hopefully you can find a different way to solve your problem.

on 2006-05-17 23:12

i mean is there some portable way of getting the value via some method call somewhere? for instance how do i portably get the value for the highest possible number returned by rand called w/o any args? thanks

on 2006-05-17 23:21

From the rand(3) manpage: "The rand() function returns a pseudo-random integer between 0 and RAND_MAX."

on 2006-05-17 23:24

On Thu, May 18, 2006 at 06:10:41AM +0900, Francis Cianfrocca wrote: > I'd expect it to be platform-dependent. I also think this is one of those > questions that are better off not asked :-) so hopefully you can find a > different way to solve your problem. f = (1.0 - Float::EPSILON) # => 1.0 (1.0 - Float::EPSILON) == 1.0 # => false "%.20f" % f # => "0.99999999999999977796"

on 2006-05-17 23:28

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... Incidentally, something is wrong with Float::EPSILON, which Mauricio suggested and should (AFAIK) work: irb(main):016:0* f = (1.0 - Float::EPSILON) => 1.0 irb(main):017:0> "%.20f" % f => "0.99999999999999977796" irb(main):019:0> x[0]-f => 1.11022302462516e-16 Whaa???

on 2006-05-17 23:44

Floating point libraries are really weird and platform-dependent, especially in regard to subtraction, which doesn't behave very well between numbers that are many orders of magnitude apart. What happens on your hardware if you do 1.0 + Float::EPSILON? Again, it seems to me that the OP might want to look for a more portable way to solve his problem.

on 2006-05-17 23:53

Joel VanderWerf wrote: > > (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.

on 2006-05-18 00:05

Without knowing your hardware and software, I can only guess, but when you subtract two numbers that are as far apart as 1.0 and Epsilon, the operation has a tendency to throw away most or all of the significant digits.

on 2006-05-18 00:51

On Thu, May 18, 2006 at 06:52:18AM +0900, Joel VanderWerf wrote: > > => "?\357\377\377\377\377\377\377" > That was completely wrong, please ignore. > 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"

on 2006-05-18 00:58

```
On 5/17/06, Francis Cianfrocca <garbagecat10@gmail.com> wrote:
> Floating point libraries are really weird and platform-dependent
yeah -- this is actually playing with fire, really.
```

on 2006-05-18 02:52

On May 17, 2006, at 4:55 PM, polypus wrote: > > how do i get the greatest float smaller than 1.0? > > thanks > > -- > Posted via http://www.ruby-forum.com/. > 1.0 - Float::EPSILON

on 2006-05-18 08:25

Hi, The right answer is that of Mauricio 1 - Float::EPSILON/2 corresponding to a significand of all ones and an effective exponent of -1. 1.0 - Float::EPSILON does have an exponent of -1 but the LSB of the significand is 0: [1 - Float::EPSILON/2].pack("G").unpack("B*") # => ["0011111111101111111111111111111111111111111111111111111111111111"] [1 - Float::EPSILON].pack("G").unpack("B*") # => ["0011111111101111111111111111111111111111111111111111111111111110"]

on 2006-05-18 10:42

On 5/18/06, Francis Cianfrocca <garbagecat10@gmail.com> wrote: > Without knowing your hardware and software, I can only guess, but when you > subtract two numbers that are as far apart as 1.0 and Epsilon, the operation > has a tendency to throw away most or all of the significant digits. The technical term for this unfortunate situation is significance loss, and it has a tendency to make otherwise elegant mathematical formulas behave like pigs when translated to floating point code. See what happens when you try to subtract two floating point numbers that are very close in magnitude, such as 1.234568 and 1.234566. Both numbers have seven significant digits, but their difference 0.000002, has only one. This particularly affects things like the summation of alternating series and recursion relations, and other places where subtraction is often used, such as with the quadratic formula... To anyone out there who is engaged in coding these sorts of things a lot, I would strongly recommend that they at the very least try reading a book like Forman S. Acton's "Numerical Methods that Work" and/or W.H. Press (et. al.) "Numerical Recipes" before they proceed. I've had these kinds of things bite me in the past, developing answers that were totally wrong, even though the formulae in use were apparently correct. And they would have been, had my floating point numbers been arbitrary precision numbers instead! It's issues such as this that usually make it better and safer to use well-tested numerics libraries where they exist rather than rolling your own.

on 2006-05-25 07:06

```
polypus wrote:
> thanks everyone for your advice
By the way, the problem in your question lies with calculus. Fact is, in
reality, there IS no 'smallest real number greater than 1'. (not even
for rational numbers). Here's proof: Say someone gives you a number x
which they claim is such a number. Then consider
h = (1 + x) / 2
h is smaller than x, but still bigger than 1. So you can always keep
getting closer to 1, and no number will be 'smallest'.
As such, the answer you got from everyone was 'what is the smallest
number that my computer will CONSIDER to be greater than one'? And that
depends on your computer. This is why the Epsilon answer works best.
```

on 2006-05-25 07:08

Pardon, you were looking for the other direction :) Ohad Lutzky wrote: > polypus wrote: >> thanks everyone for your advice > > By the way, the problem in your question lies with calculus. Fact is, in > reality, there IS no 'greatest real number smaller than 1'. (not even > for rational numbers). Here's proof: Say someone gives you a number x > which they claim is such a number. Then consider > > h = (1 - x) / 2 > > h is greater than x, but still smaller than 1. So you can always keep > getting closer to 1, and no number will be 'greatest'. > > As such, the answer you got from everyone was 'what is the greatest > number that my computer will CONSIDER to be smaller than one'? And that > depends on your computer. This is why the Epsilon answer works best.

on 2006-05-25 11:05

On 5/17/06, polypus <polypus@yahoo.com> wrote: > > > how do i get the greatest float smaller than 1.0? > > thanks > > -- > Posted via http://www.ruby-forum.com/. > > I agree with the answers that this question is dangerous and meaningless unless it is not. Assuming that you know what you need this is one way how the ruby interpreter can tell you what that number might be (from its point of view), although it should not exist ;) You have be warned about all kind of issues I will not repeat them. Cheers Robert ------------------------ 8< -------------------------------- #!/usr/bin/env ruby delta = Float::EPSILON while (y = 1.0 - delta) < 1.0 do delta /= 2.0 puts "%0.30f %0.30f" % [delta, y] end puts "%0.30f %0.30f" % [delta, y] On my machine I get robert@roma:~/ruby/tests$ ruby float.rb 0.000000000000000111022302462516 0.999999999999999777955395074969 0.000000000000000055511151231258 0.999999999999999888977697537484 0.000000000000000055511151231258 1.000000000000000000000000000000 you might get something else. -- Deux choses sont infinies : l'univers et la bÃªtise humaine ; en ce qui concerne l'univers, je n'en ai pas acquis la certitude absolue. - Albert Einstein