Greatest float smaller than 1.0?


#1

how do i get the greatest float smaller than 1.0?

thanks


#2

Analysis?


#3

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


#4

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


#5

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


#6

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


#7

On Thu, May 18, 2006 at 06:10:41AM +0900, Francis C. wrote:

I’d expect it to be platform-dependent. I also think this is one of those
questions that are better off not asked :slight_smile: 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”


#8

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???


#9

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.


#10

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.


#11

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”


#12

On 5/17/06, Francis C. removed_email_address@domain.invalid wrote:

Floating point libraries are really weird and platform-dependent

yeah – this is actually playing with fire, really.


#13

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.


#14

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


#15

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”]


#16

thanks everyone for your advice


#17

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.


#18

On 5/18/06, Francis C. removed_email_address@domain.invalid 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.


#19

Pardon, you were looking for the other direction :slight_smile:

Ohad L. 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.


#20

On 5/17/06, polypus removed_email_address@domain.invalid 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 :wink:
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