[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Integer division with / - request explanation of behavior

Wes Gamble

9/30/2006 8:07:00 AM

Today I discovered the difference in the meaning of the / (arithmetic
divide) method depending on whether it's caller is an integer or a
float.

I discovered that I had to cast the calling number explicitly to a float
and it seemed totally non-intuitive to me.

A couple of points:

1) I just discovered that this behavior exists in Java and C as well.
Which, frankly, I didn't even realize. Sigh.

2) I've read some other posts and people have mentioned the notion of
type purity with respect to this. I don't see why that's a problem.
When one divides two integers, one isn't asking for one of the integer
arguments to be cast to a float, they're asking for the result of
dividing two integers. Since when is it not allowable for a method to
take arguments of a given type and return a result of a different type?

A couple of questions:

1) I see that there is a divmod operator in Ruby that returns the
quotient and remainder of a division. Why is the overridden / operator
necessary when there is already a way to get int1 DIV int2 by using
int1.divmod(int2)[0]?

2) Is the reason for the behavior of "/" is that this is the behavior of
"/" in C? Why is it that way in C?

Thanks,
Wes

--
Posted via http://www.ruby-....

17 Answers

Paul Lutus

9/30/2006 9:24:00 AM

0

Wes Gamble wrote:

> Today I discovered the difference in the meaning of the / (arithmetic
> divide) method depending on whether it's caller is an integer or a
> float.

Not exactly. The result is expressed in the type of the more precise of the
two operands.

>
> I discovered that I had to cast the calling number explicitly to a float
> and it seemed totally non-intuitive to me.

Well, that depends on what you want as a result. You aren't required to cast
one of the operands as a float. Maybe you want the default result for the
provided values.

I often break a time value into hours, minutes and seconds. I do this by
successive application of integer modulo and divide. If the division
operator were to promote my values, the algorithm would fail.

> A couple of points:
>
> 1) I just discovered that this behavior exists in Java and C as well.
> Which, frankly, I didn't even realize. Sigh.

There are excellent reasons for this behavior. When you divide two numbers,
the result should have the precision of the more precise type of either of
the two operands.

> 2) I've read some other posts and people have mentioned the notion of
> type purity with respect to this. I don't see why that's a problem.

It's not about type purity. That isn't supported by the fact that the less
precise type is discarded in favor of the more precise type.

> When one divides two integers, one isn't asking for one of the integer
> arguments to be cast to a float, they're asking for the result of
> dividing two integers. Since when is it not allowable for a method to
> take arguments of a given type and return a result of a different type?

It is not a question of allowed, it is a question of what one would expect
without explicit adjustment.

>
> A couple of questions:
>
> 1) I see that there is a divmod operator in Ruby that returns the
> quotient and remainder of a division. Why is the overridden / operator
> necessary when there is already a way to get int1 DIV int2 by using
> int1.divmod(int2)[0]?

Because people expect to be able to use a division operator for division.

> 2) Is the reason for the behavior of "/" is that this is the behavior of
> "/" in C? Why is it that way in C?

This behavior is common to all modern languages. It exists because the
languages that support it are designed to act on a set of common-sense
assumptions.

BTW, the behavior goes beyond integers and floats. It also applies to
extended-precision numerical types.

x = BigDecimal.new("3.0",100)

puts 1/x

0.333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333E0

One of the operands is an integer, but the result is cast to the precision
of the more precise type. So much for type purity.

--
Paul Lutus
http://www.ara...

Vincent Fourmond

9/30/2006 11:53:00 AM

0


Hello !

> 2) Is the reason for the behavior of "/" is that this is the behavior of
> "/" in C? Why is it that way in C?

Here's a couple of reasons:

* C is mapping this operation directly to assembly. Old x86 processors
used to be able to manipulate only integers, so the result of the
division of one integer by another had to be an integer;

* the architecture for processing floats is way more complex and less
portable than the one from integers (integer arithmetic is the same on
every single processor in the world; float arithmetic is a nightmare);

* floats are much slower to manipulate, even in assembly code;

* in ruby, integers are hard-coded as immediate values, whereas floats
are embedded into a complex data structure. You wouldn't want to invoke
a really heavy machinery for an integer division...

Does that sound correct to you ?

Cheers,

Vince

Robert Klemme

9/30/2006 12:45:00 PM

0

Paul Lutus wrote:
>> 2) Is the reason for the behavior of "/" is that this is the behavior of
>> "/" in C? Why is it that way in C?
>
> This behavior is common to all modern languages. It exists because the
> languages that support it are designed to act on a set of common-sense
> assumptions.
>
> BTW, the behavior goes beyond integers and floats. It also applies to
> extended-precision numerical types.

And as far as I know it's even an IEEE standard. Programming systems
better comply with it in order to make results comparable and
interchangeable.

Kind regards

robert

Eero Saynatkari

9/30/2006 3:11:00 PM

0

On 2006.09.30 18:25, Paul Lutus wrote:
> Wes Gamble wrote:
>
> > Today I discovered the difference in the meaning of the / (arithmetic
> > divide) method depending on whether it's caller is an integer or a
> > float.
>
> Not exactly. The result is expressed in the type of the more precise of the
> two operands.

Actually, integers are more precise than IEEE floating points
since 2.2 - 1.2 != 1.0 :) s/precise/accurate !

Paul Lutus

9/30/2006 3:42:00 PM

0

Eero Saynatkari wrote:

> On 2006.09.30 18:25, Paul Lutus wrote:
>> Wes Gamble wrote:
>>
>> > Today I discovered the difference in the meaning of the / (arithmetic
>> > divide) method depending on whether it's caller is an integer or a
>> > float.
>>
>> Not exactly. The result is expressed in the type of the more precise of
>> the two operands.
>
> Actually, integers are more precise than IEEE floating points
> since 2.2 - 1.2 != 1.0 :) s/precise/accurate !

Yes, I used the wrong term. I should have said "longer" rather than more
precise. Even that is less true than it used to be, as what is generally
accepted to be an int changes over time.

Float and double math is at least reliable in its unreliability. :)

--
Paul Lutus
http://www.ara...

Paul Lutus

9/30/2006 4:02:00 PM

0

Robert Klemme wrote:

/ ...

>> BTW, the behavior goes beyond integers and floats. It also applies to
>> extended-precision numerical types.
>
> And as far as I know it's even an IEEE standard.

I think that's true also, but certainly type promotion is what people expect
to happen.

> Programming systems
> better comply with it in order to make results comparable and
> interchangeable.

There's a can of worms. It turns out the behavior of the different languages
WRT conversion from and to base ten leads to some borderline failures if
the textual forms are transferred between environments.

As it turns out Perl is one of the worst as far as being able to recreate
its own internal binary representation based on its self-generated textual
representation. I became comfortable (perhaps too comfortable) with being
able to convert doubles back and forth between string and binary form,
reliably and repeatably, in most languages, but I couldn't make this happen
in Perl (version 4.0 IIRC).

Without realizing it, I had come to assume that a language's base ten
textual representation for a double or a float would be readable by that
same language and when reconverted (base ten -> base two) produce an exact
copy of the original binary form, and this is true in most languages. Then
a Perl programmer challenged me on this, saying the base ten representation
almost never recreated the original binary number, and I tried to show that
wasn't true. I wrote test suites in Java, C and C++ (the latter not using
printf and scanf) and Perl, and the results were perfect in every language
except Perl.

At this point, that observation may be more history than fact, because of
the increasing importance of data transfers between environments.

--
Paul Lutus
http://www.ara...

David Vallner

9/30/2006 4:09:00 PM

0

Wes Gamble wrote:
> Today I discovered the difference in the meaning of the / (arithmetic
> divide) method depending on whether it's caller is an integer or a
> float.
>
> I discovered that I had to cast the calling number explicitly to a float
> and it seemed totally non-intuitive to me.
>

The mathn namespace-clobbering module makes maths work like expected.

The magic lies in aliasing Fixnum#/ to Fixnum#quo (same for Bignum).

You could use that method explicitly, or just clobber the classes if
you're sure nothing else expects the C meaning to work.

Wes Gamble

9/30/2006 4:27:00 PM

0

> I frankly think there are two reasons for it
> (1) Matz thaught it is more useful that way
> and/or
> (2) Matz thaught it is POLS
> these are good reasons of course ;).

POLS?

--
Posted via http://www.ruby-....

M. Edward (Ed) Borasky

9/30/2006 4:32:00 PM

0

Paul Lutus wrote:
> Without realizing it, I had come to assume that a language's base ten
> textual representation for a double or a float would be readable by that
> same language and when reconverted (base ten -> base two) produce an exact
> copy of the original binary form, and this is true in most languages. Then
> a Perl programmer challenged me on this, saying the base ten representation
> almost never recreated the original binary number, and I tried to show that
> wasn't true. I wrote test suites in Java, C and C++ (the latter not using
> printf and scanf) and Perl, and the results were perfect in every language
> except Perl.
>
> At this point, that observation may be more history than fact, because of
> the increasing importance of data transfers between environments.

Long ago in a galaxy far away, there were many more choices for transfer
of data from one machine to another. And someone coined the rule "The
receiver makes it right".



Matthias Reitinger

9/30/2006 4:34:00 PM

0

Wes Gamble wrote:
>> I frankly think there are two reasons for it
>> (1) Matz thaught it is more useful that way
>> and/or
>> (2) Matz thaught it is POLS
>> these are good reasons of course ;).
>
> POLS?

Principle Of Least Surprise.