Hello.

I have a simple question - how to detect if a variable contains a Float

of value -0.0? Is there any special method for this, or any comparison

that distinguishes negative zero from a the regular zero?

Thanks in advance.

TPR.

Hello.

I have a simple question - how to detect if a variable contains a Float

of value -0.0? Is there any special method for this, or any comparison

that distinguishes negative zero from a the regular zero?

Thanks in advance.

TPR.

Thomas B. wrote:

Hello.

I have a simple question - how to detect if a variable contains a Float

of value -0.0? Is there any special method for this, or any comparison

that distinguishes negative zero from a the regular zero?Thanks in advance.

TPR.

irb(main):001:0> x = -0.0

=> -0.0

irb(main):002:0> x == 0.0

=> true

irb(main):003:0> x.eql?(0.0)

=> true

irb(main):004:0> x.equal?(0.0)

=> false

Thomas B. wrote:

of value -0.0? Is there any special method for this, or any comparison

that distinguishes negative zero from a the regular zero?

irb(main):001:0> 1/-0.0 < 0

=> true

irb(main):002:0> 1/0.0 < 0

=> false

-Matthias

Thank you

Joel,

your answer is not very helpful as 0.0.equals?(0.0) also returns false.

Matthias,

irb(main):001:0> 1/-0.0 < 0

=> true

irb(main):002:0> 1/0.0 < 0

=> false

thanks, that’s just the obvious thing that I have overlooked! Changing

the difference between zeros to the difference between infinities.

TPReal.

Joel VanderWerf wrote:

Thomas B. wrote:

Hello.

of value -0.0? Is there any special method for this, or any comparison

that distinguishes negative zero from a the regular zero?Thanks in advance.

TPR.irb(main):001:0> x = -0.0

=> -0.0

irb(main):002:0> x == 0.0

=> true

irb(main):003:0> x.eql?(0.0)

=> true

irb(main):004:0> x.equal?(0.0)

=> false

irb(main):001:0> x = 0.0

=> 0.0

irb(main):002:0> x == 0.0

=> true

irb(main):003:0> x.eql?(0.0)

=> true

irb(main):004:0> x.equal?(0.0)

=> false

In short: you cannot distinguish between 0.0 and -0.0 this way.

-Matthias

Thomas B. wrote:

Hello.

of value -0.0? Is there any special method for this, or any comparison

that distinguishes negative zero from a the regular zero?

NB: I’m not sure how portable this is.

def negative_zero?(number)

inverse = 1 / number.to_f

inverse < 0 && inverse.infinite? ? true : false

end

[ 0.0, # false

-0.0, # true

-1.0, # false

1.0 # false

].each do |f|

puts negative_zero?(f)

end

Jeff S. wrote:

irb(main):001:0> (-0.0).equal? -0.0

=> false

Oops. That never seemed right to me. Float#equal? should hide the fact

that floats are allocated, and not immediate.

It has always seemed like a leaky abstraction this way.

Joel VanderWerf wrote:

irb(main):001:0> x = -0.0

=> -0.0

irb(main):002:0> x == 0.0

=> true

irb(main):003:0> x.eql?(0.0)

=> true

irb(main):004:0> x.equal?(0.0)

=> false

What does that accomplish?

irb(main):001:0> (-0.0).equal? -0.0

=> false

Joel VanderWerf wrote:

Oops. That never seemed right to me. Float#equal? should hide the fact

that floats are allocated, and not immediate.

Why would it? It doesn’t do it for any other type of object. And if it

would,

what would be the difference to == ?

On 28.04.2009 22:27, Jeff S. wrote:

inverse = 1 / number.to_f

inverse < 0 && inverse.infinite? ? true : false

Why do you use the ternary operator to convert a boolean into a boolean?

end

[ 0.0, # false

-0.0, # true

-1.0, # false

1.0 # false

].each do |f|

puts negative_zero?(f)

end

My 0.02 EUR: normally there should not be any distinction between 0.0

and -0.0. Even though computer math is not the same as real math, the

distinction does not seem to make sense to me.

Kind regards

robert

Sebastian H. wrote:

Joel VanderWerf wrote:

Oops. That never seemed right to me. Float#equal? should hide the fact

that floats are allocated, and not immediate.Why would it? It doesn’t do it for any other type of object. And if it would,

what would be the difference to == ?

Because it is only a quirk of cpu architecture that forces them to be

allocated rather than immediate. Maybe some future ruby implementation

(on >32 bit systems) will use immediate double-precision floats. Other

types will never be immediate.

The difference to #== would be the same as today: #== performs numeric

type conversions (and consequently erases the difference between 0.0 and

-0.0). But #equal? never would.

Gary W. removed_email_address@domain.invalid writes:

[…]

A quick look at the IEEE format suggests that there are (2^51 - 1) bit

patterns that are all considered NaN (not a number).Seems like it might be possible to encode Ruby references in there.

Does anyone know of a language implementation that tags references in

that way?

Some specific NaN are produced by arithmetic operations.

Does IEEE forbid a FP unit to generate any NaN for some operations?

It would seem to me to be dangerous to be able to produce random

references from arithmetic operations…

On Apr 28, 2009, at 4:59 PM, Joel VanderWerf wrote:

implementation (on >32 bit systems) will use immediate double-

precision floats. Other types will never be immediate.

A quick look at the IEEE format suggests that there are (2^51 - 1) bit

patterns that are all considered NaN (not a number).

Seems like it might be possible to encode Ruby references in there.

Does anyone know of a language implementation that tags references in

that way?

Gary W.

Robert K. wrote:

def negative_zero?(number)

inverse = 1 / number.to_f

inverse < 0 && inverse.infinite? ? true : falseWhy do you use the ternary operator to convert a boolean into a boolean?

I don’t. Float#infinite? can return nil, -1, or +1, but never true or

false. Without the ternary, the original client code produces the

following, far less meaningful output, including the blank line:

false

-1

false

end

[ 0.0, # false

-0.0, # true

-1.0, # false

1.0 # false

].each do |f|

puts negative_zero?(f)

end

My 0.02 EUR: normally there should not be any distinction between 0.0

and -0.0. Even though computer math is not the same as real math, the

distinction does not seem to make sense to me.

“Real” math? Whatever you say. In EE college courses, professors often

use -0 to represent the limit of an asymptotic function that approaches

zero from the negative side, e.g. the voltage decay of a negatively

charged capacitor. The use has nothing to do with computers or IEEE

floats.

Anyway, take it up with the OP; AFAIK, his question was academic, but

maybe he has an interesting use case.

Pascal J. Bourguignon wrote:

Some specific NaN are produced by arithmetic operations.

Does IEEE forbid a FP unit to generate any NaN for some operations?It would seem to me to be dangerous to be able to produce random

references from arithmetic operations…

The interpreter would have to add code to check for that and replace

with some canonical NaN that doesn’t conflict.

The ruby runtime already has to call rb_float_new() on the result of

every floating point function. Doing this check instead would be less

overhead.

On 29.04.2009 17:39, Jeff S. wrote:

false

-1false

Well, but all these are perfectly boolean values in Ruby. There is no

need to convert the expression other than for display maybe. But in

that case I’d do the conversion outside the method as it does not add

any semantics to the method implementation but costs time.

Kind regards

robert

Robert K. wrote:

following, far less meaningful output, including the blank line:

false

-1false

Well, but all these are perfectly boolean values in Ruby.

They can be used seamlessly in boolean contexts, but that does not make

them boolean values in the sense that true and false are.

There is no

need to convert the expression other than for display maybe.

You mean, like, maybe in a Usenet post?

But in

that case I’d do the conversion outside the method as it does not add

any semantics to the method implementation but costs time.

Have you done enough profiling to demonstrate that there is in fact a

performance penalty, and that it justifies adding complexity to the

client code? Silliness. Let the function return consistent,

predictable values, and quit your whining.

On Apr 28, 3:07 pm, “Thomas B.” removed_email_address@domain.invalid wrote:

Hello.

of value -0.0? Is there any special method for this, or any comparison

that distinguishes negative zero from a the regular zero?## Thanks in advance.

TPR.Posted viahttp://www.ruby-forum.com/.

shouldnt converting it to a String and then testing for the presence

of ‘-’ work?

Jeff S. wrote:

“Real” math? Whatever you say. In EE college courses, professors often

use -0 to represent the limit of an asymptotic function that approaches

zero from the negative side, e.g. the voltage decay of a negatively

charged capacitor. The use has nothing to do with computers or IEEE

floats.Anyway, take it up with the OP; AFAIK, his question was academic, but

maybe he has an interesting use case.

In fact, the -0.0 in programming is not very similar to the real math

lim_{x->0-}(x). The simplest proof of this is the fact that -(1.0-1.0)

gives -0.0, while after pushing the minus into the parenthesis we get

-1.0+1.0 which gives 0.0. So I wouldn’t say that -0.0 resembles the

limes of capacitor charge, maybe only a bit. But if we wanted some more

real math logic, we would need also +0.0 (different from 0.0), begin the

result of 1.0/infinity. Then we would have -(+0.0) = -0.0, but -(0.0) =

0.0. But still it’s only some approximation of “real math”.

Because of these inconsistency in IEEE (inconsistency with the real math

or physics, I mean, not in IEEE itself), I’m not trying to use -0.0 as a

real limes of something. The real use case is as follows (if anybody

should be interested):

A car can drive forward or reverse, but after it brakes to stop after,

say, going forward, it needs to spend a short time staying still before

it can start going backwards. This is a way of modelling the time needed

to switch the gear from 1 and R (and the same applies to switching from

R to 1). So now if I’m controlling the car, then I should be able to

give it the desired velocity (the set point to a controller). So I

decided that 0.0 means “don’t move and be ready to go forward

immediately (while I know there will be a moment’s pause if I want to go

backwards now)”, while -0.0 means “don’t move but stay switched to

reverse, so that there’s no time needed to start driving reverse (while

a moment will be needed should I decide to go forward)”. That’s it, just

one more bit of information pushed into the value of zero, which is

exactly where I need it.

TPR.