how do i get the greatest float smaller than 1.0?

thanks

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

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.

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

From the rand(3) manpage: “The rand() function returns a

pseudo-random

integer between 0 and

RAND_MAX.”

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

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

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.

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

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

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

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

Pardon, you were looking for the other direction

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 considerh = (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 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

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

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