I’d like to be able to do:

x = 2.0

assert x.integral?

the :integer method returns false in this case.

What would be a good way to write a different method to check?

I’d like to be able to do:

x = 2.0

assert x.integral?

the :integer method returns false in this case.

What would be a good way to write a different method to check?

On Nov 14, 2006, at 10:35 AM, S. Robert J. wrote:

I’d like to be able to do:

x = 2.0

assert x.integral?the :integer method returns false in this case.

What would be a good way to write a different method to check?

2.0.is_a? Float

=> true2.0.is_a? Integer

=> false

James Edward G. II

Hope the following helps:

irb(main):001:0> 2.0.class

=> Float

irb(main):002:0> 2.class

=> Fixnum

irb(main):003:0> 2.0.is_a?(Float)

=> true

irb(main):004:0> 2.0.is_a?(Fixnum)

=> false

irb(main):005:0> 2.is_a?(Float)

=> false

irb(main):006:0> 2.is_a?(Fixnum)

=> true

-Szymon

S. Robert J. wrote:

I’d like to be able to do:

x = 2.0

assert x.integral?

What would be a good way to write a different method to check?

That depends on what you are trying to accomplish. Are you trying to

establish that the value is an integer expressed as a float?

#!/usr/bin/ruby -w

def integer_in_sheeps_clothing?(v)

return v.to_i == v

end

puts integer_in_sheeps_clothing?(5.0)

puts integer_in_sheeps_clothing?(5.0 + 1e-10)

Output:

true

false

On 11/14/06, S. Robert J. [email protected] wrote:

I’d like to be able to do:

x = 2.0

assert x.integral?

What would be a good way to write a different method to check?

class Numeric

def is_integer?

Integer(self) == self

end

end

2.0.is_integer? #=> true

2.1.is_integer? #=> false

2.is_integer? #=> true

Blessings,

TwP

On 11/14/06, [email protected] [email protected] wrote:

asking if two values are within some delta (also represented as a

floating

point value) of each other.Any numerical computation folks out there who can share their wisdom?

Maybe the value should be modeled as an integer with different units

instead of floating point? For example using units of pennies instead

of dollars to model monetary values.

IEEE floating point can store an exact representation of any integer

that the fp number is large enough to contain.

I’ve never used it this way, but supposedly that is used to handle

53-bit ints on platforms that have 64-bit floats and only 32-bit ints.

That may or may not be what the OP is trying to do.

On Nov 14, 2006, at 2:21 PM, Wilson B. wrote:

IEEE floating point can store an exact representation of any integer

that the fp number is large enough to contain.

I’ve never used it this way, but supposedly that is used to handle

53-bit ints on platforms that have 64-bit floats and only 32-bit ints.That may or may not be what the OP is trying to do.

I’m pretty sure Lua uses floats for everything, for exactly this reason.

James Edward G. II

James Edward G. II wrote:

On Nov 14, 2006, at 2:21 PM, Wilson B. wrote:

IEEE floating point can store an exact representation of any integer

that the fp number is large enough to contain.

I’ve never used it this way, but supposedly that is used to handle

53-bit ints on platforms that have 64-bit floats and only 32-bit ints.That may or may not be what the OP is trying to do.

I’m pretty sure Lua uses floats for everything, for exactly this reason.

How does that work? Is there an 11-bit pattern that signifies “use the

remaining 53 bits as a integer”? Do math library functions respect this?

On Nov 14, 2006, at 2:29 PM, Joel VanderWerf wrote:

reason.

How does that work? Is there an 11-bit pattern that signifies “use

the remaining 53 bits as a integer”? Do math library functions

respect this?

I have no idea how they do what they do:

http://lua-users.org/wiki/FloatingPoint

James Edward G. II

On Nov 14, 2006, at 11:35 AM, S. Robert J. wrote:

I’d like to be able to do:

x = 2.0

assert x.integral?

What would be a good way to write a different method to check?

Maybe it is just me, I don’t have a lot of experience with floating

point

issues, but this request has a bad smell to it. Once you’ve decided to

model something with floating point values it seems a bit unusual to

want

to know if any particular value happens to be the exact floating point

representation of an integer. Isn’t the entire notion of equality

somewhat

ambiguous in the floating point world? I thought this is usually

handled by

asking if two values are within some delta (also represented as a

floating

point value) of each other.

Any numerical computation folks out there who can share their wisdom?

Maybe the value should be modeled as an integer with different units

instead of floating point? For example using units of pennies instead

of dollars to model monetary values.

Gary W.

Sander L. wrote:

On 11/14/06, Joel VanderWerf [email protected] wrote:

How does that work? Is there an 11-bit pattern that signifies “use the

remaining 53 bits as a integer”? Do math library functions respect this?53 bits is just the mantissa size.

imagine using scientific notation a * 10^b with a<1 and 3 decimal

digits, this gives you accurate integers up to 1000.

999 => 0.999 * 10^3 exact

1001=> 0.100 * 10^4 overflowed

Ok, so they aren’t doing anything exceptional with the format. There’s

no special switching going on, just normal floating point math with

integer values.

On 11/14/06, Joel VanderWerf [email protected] wrote:

remaining 53 bits as a integer”? Do math library functions respect this?

53 bits is just the mantissa size.

imagine using scientific notation a * 10^b with a<1 and 3 decimal

digits, this gives you accurate integers up to 1000.

999 => 0.999 * 10^3 exact

1001=> 0.100 * 10^4 overflowed

But depending upon how the “integer” was generated, it may still make

more sense to use an epsilon in the test (which certainly has the

“smell” that was mentioned earlier)

Integer(100.0 * 9.95) == 995 => false

(100.0 * 9.95) - 995.0 <= Float::EPSILON => true

class Float

def like_an_int

(self - self.round).abs <= Float::EPSILON

end

end

(100.0 * 9.95).like_an_int => false

On my system Float::EPSILON = 2.22044604925031e-016

(100.0 * 9.95) - 995.0 => -1.13686837721616e-013

Which is way bigger than EPSILON, it turns out you need to scale your

“EPSILON” by the relative magnitude of the numbers being compared.

This way leads to madness and general discomfort --> if you find

yourself in this neighborhood, switch to rational numbers (or scaled

integers), you will be happier.

pth

Bernard K. wrote:

/ …

What would be a good way to write a different method to check?x.class => Float 2.0 is a float not an integer

The OP is trying to establish whether the *content* of the float

variable is

an integer, not whether the variable has float type. That is relatively

easy to establish.

----- Original Message -----

From: “S. Robert J.” [email protected]

Newsgroups: comp.lang.ruby

To: “ruby-talk ML” [email protected]

Sent: Tuesday, November 14, 2006 11:35 AM

Subject: Is 2.0 Integer or Float?

I’d like to be able to do:

x = 2.0

assert x.integral?

What would be a good way to write a different method to check?

x.class => Float 2.0 is a float not an integer

Paul L. wrote:

Bernard K. wrote:

What would be a good way to write a different method to check?x.class => Float 2.0 is a float not an integer

The OP is trying to establish whether the

contentof the float

variable is

an integer, not whether the variable has float type. That is relatively

easy to establish.

Sorry to join this conversation late, but to me this is a strange

question. Floats are never integers. Integers are counting numbers with

exact values over a certain range determined by their internal

representation. While floating point numbers are approximations which

suffer from errors of precision. They may approach an integer bound and

yet never achieve it. So the question is what approximation is adequate

to say that a float is the integer that it approaches. What is close

enough?

Example:

irb(main):124:0> def is_integer(f)

irb(main):125:1> ((f.ceil - f).remainder(1).abs < 0.0000000001) or

((f.floor - f

).remainder(1).abs < 0.0000000001)

irb(main):126:1> end

=> nil

irb(main):127:0> n = 0.1

=> 0.1

irb(main):128:0> 100.times { puts “#{n} is a integer: #{is_integer(n)}”;

n += 0.

1 }

0.1 is a integer: false

0.2 is a integer: false

0.3 is a integer: false

0.4 is a integer: false

0.5 is a integer: false

0.6 is a integer: false

0.7 is a integer: false

0.8 is a integer: false

0.9 is a integer: false

1.0 is a integer: true

1.1 is a integer: false

1.2 is a integer: false

1.3 is a integer: false

1.4 is a integer: false

1.5 is a integer: false

1.6 is a integer: false

1.7 is a integer: false

1.8 is a integer: false

1.9 is a integer: false

2.0 is a integer: true

2.1 is a integer: false

2.2 is a integer: false

2.3 is a integer: false

2.4 is a integer: false

2.5 is a integer: false

2.6 is a integer: false

2.7 is a integer: false

2.8 is a integer: false

2.9 is a integer: false

3.0 is a integer: true

3.1 is a integer: false

3.2 is a integer: false

3.3 is a integer: false

3.4 is a integer: false

3.5 is a integer: false

3.6 is a integer: false

3.7 is a integer: false

3.8 is a integer: false

3.9 is a integer: false

4.0 is a integer: true

4.1 is a integer: false

4.2 is a integer: false

4.3 is a integer: false

4.4 is a integer: false

4.5 is a integer: false

4.6 is a integer: false

4.7 is a integer: false

4.8 is a integer: false

4.9 is a integer: false

5.0 is a integer: true

5.1 is a integer: false

5.2 is a integer: false

5.3 is a integer: false

5.4 is a integer: false

5.5 is a integer: false

5.6 is a integer: false

5.7 is a integer: false

5.8 is a integer: false

5.9 is a integer: false

5.99999999999999 is a integer: true

6.09999999999999 is a integer: false

6.19999999999999 is a integer: false

6.29999999999999 is a integer: false

6.39999999999999 is a integer: false

6.49999999999999 is a integer: false

6.59999999999999 is a integer: false

6.69999999999999 is a integer: false

6.79999999999999 is a integer: false

6.89999999999999 is a integer: false

6.99999999999999 is a integer: true

7.09999999999999 is a integer: false

7.19999999999999 is a integer: false

7.29999999999999 is a integer: false

7.39999999999999 is a integer: false

7.49999999999999 is a integer: false

7.59999999999999 is a integer: false

7.69999999999999 is a integer: false

7.79999999999999 is a integer: false

7.89999999999999 is a integer: false

7.99999999999999 is a integer: true

8.09999999999999 is a integer: false

8.19999999999999 is a integer: false

8.29999999999999 is a integer: false

8.39999999999999 is a integer: false

8.49999999999999 is a integer: false

8.59999999999999 is a integer: false

8.69999999999999 is a integer: false

8.79999999999998 is a integer: false

8.89999999999998 is a integer: false

8.99999999999998 is a integer: true

9.09999999999998 is a integer: false

9.19999999999998 is a integer: false

9.29999999999998 is a integer: false

9.39999999999998 is a integer: false

9.49999999999998 is a integer: false

9.59999999999998 is a integer: false

9.69999999999998 is a integer: false

9.79999999999998 is a integer: false

9.89999999999998 is a integer: false

9.99999999999998 is a integer: true

Dale M. wrote:

Paul L. wrote:

/ …

The OP is trying to establish whether the

contentof the float

variable is

an integer, not whether the variable has float type. That is relatively

easy to establish.Sorry to join this conversation late, but to me this is a strange

question. Floats are never integers.

That depends on how we are defining our terms. In a mathematical sense,

of

course, yes. In a computer-science sense however, one can place an

integer

in a float variable, and it will behave itself as though it were an

integer

– for example, regardless of its value (within the allowed range), it

will

permit itself to be converted between bases without any of the

well-documented gotchas to which true floats are prone. Also, additions,

subtractions and multiplies will be carried out with the expected

integer

results.

Integers are counting numbers with

exact values over a certain range determined by their internal

representation.

And such an integer can be stored in a float variable type.

While floating point numbers are approximations which

suffer from errors of precision.

This refers to floats in float variables, not integers in float

variables.

They may approach an integer bound and

yet never achieve it. So the question is what approximation is adequate

to say that a float is the integer that it approaches. What is close

enough?

No, as a matter of fact, an integer stored in a float variable type

doesn’t

lose its identity as an integer. It is still an integer, and behaves

itself

in a way that a float cannot.

All your examples prove is that floats are not integers. But, hear me on

this, integers really are integers, no matter where they are located,

assuming they do not overflow the range of the variable in which they

are

stored.

#!/usr/bin/ruby -w

fi = i.to_f

puts “Error: #{i}” if(i != fi)

end

The silence was deafening. I lost patience with more repetitions, but I

think I know the outcome.

You should know that many projects store integers in float variables in

cases where the float variable has more available bits of precision that

the platform’s integer data type. Those who do this know there is no

downside – the integer stored in the float variable won’t start

misbehaving itself just because of its new, upscale quarters.

Dale M. wrote:

Paul L. wrote:

Dale M. wrote:

Paul L. wrote:

You should know that many projects store integers in float variables in

cases where the float variable has more available bits of precision that

the platform’s integer data type. Those who do this know there is no

downside – the integer stored in the float variable won’t start

misbehaving itself just because of its new, upscale quarters.

I agree that storing integers in floats is possible as long as you only

use integer values for your computations and you do not exceed a

mantissa’s precision that everything will be wonderful.

If this is the world you wish to limit yourself to then:

def is_integer(f)

f.remainder(1) == 0

end

would be adequate as a test to determine is a value stored in a float is

an integer, but this will fail on many computed values that involve

non-integer values even if the expected result should be an integer

value.

I personally don’t see a valid application in Ruby since Fixnum and

Bignum handle precision well beyond that of Float.

Paul L. wrote:

Dale M. wrote:

Paul L. wrote:

All your examples prove is that floats are not integers. But, hear me on

this, integers really are integers, no matter where they are located,

assuming they do not overflow the range of the variable in which they

are

stored.

#!/usr/bin/ruby -w

## 0.upto(1e6) do |i|

fi = i.to_f

puts “Error: #{i}” if(i != fi)

endThe silence was deafening. I lost patience with more repetitions, but I

think I know the outcome.You should know that many projects store integers in float variables in

cases where the float variable has more available bits of precision that

the platform’s integer data type. Those who do this know there is no

downside – the integer stored in the float variable won’t start

misbehaving itself just because of its new, upscale quarters.

Yes, you can store integers in floats. This is usually done with the

exponent left at zero and the size of the mantissa limits the range of

valid integers. If the exponent must be used, it becomes a computed

value that is an approximation.

Using irb,

irb(main):163:0> 1e6.class => Float

irb(main):164:0> 1e22.to_i => 10000000000000000000000

irb(main):165:0> 1e23.to_i => 99999999999999991611392

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs