Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > About Rational Number (PEP 239/PEP 240)

Reply
Thread Tools

About Rational Number (PEP 239/PEP 240)

 
 
Lie
Guest
Posts: n/a
 
      12-15-2007
I'm very surprised actually, to see that Python rejected the use of
fractional/rational numbers. However, when I read the PEP, I know
exactly why the proposal was rejected: People compared fractions with
integers, while it should be more fairly compared to floats.

Arguments against:
- When I use the result of / as a sequence index, it's usually an
error which should not be hidden by making the program working for
some data, since it will break for other data.
----> In Python 3 (and 2 w/ __future__), the / operator would always
return floats, and floats is invalid as sequence index, even if the
value of the float is whole. Since fractions is created with the /
operator on two integers, the behavior of fractions should mimics
float. So putting fractional type as sequence index should always be
considered as error (exception), a behavior consistent with floats.
Thus, the arguments specified above has turned invalid, at least in
Python 3.
- (this assumes the same type for them Int is a good type in itself,
not to be mixed with rationals. The fact that something is an integer
should be expressible as a statement about its type. Many operations
require ints and don't accept rationals. It's natural to think about
them as about different types.
----> I agree, ints shouldn't be mixed with rationals. But floats
could. This argument is the main reason why I said most people
compared rational with integers. Many operations that requires ints
and don't accept rationals also don't accept floats.

Other arguments:
- Slow: Doing addition and subtraction in fractions sure is expensive,
but doing division (the heaviest arithmetic operation) is extremely
fast in fractional numbers compared to in floating numbers. It is
clear that doing two integer multiplication and switching numerator-
denominator is much faster than doing a single float division.
- Memory Intensive: To represent 1/3 to infinite accuracy requires two-
integer-space (theoretically, 2 bytes). There are some numbers that
are hard to represent in fractions, yes, but in general those numbers
could be represented using two-long-space (variable-width longs). And
whenever accuracy isn't that important, it could be possible to create
a method that would lossily approximate the current fraction to an
acceptable length. Anyway, most computers nowadays is packed with
gigantic memory, why bother with such a small issue.
- Rationals must present themselves as decimal floats or it'll be
confusing: There will be no confusion in a good written code.
Progammers that writes good code would always use the 'behind-the-
scene' number, they wouldn't convert a previously 'string'ed number
back into calculation. And a convention can be created to represent a
fraction in a single line output (like * for multiplication, / for
division, they don't exist in paper maths) that would completely
eliminate any confusion of the user (well informed about the
convention, most people that never used computer before often tried to
use x and : to represent mult and div), even when the fractional
number is outputted to the foreground UI.

 
Reply With Quote
 
 
 
 
mensanator@aol.com
Guest
Posts: n/a
 
      12-15-2007
On Dec 15, 2:00 pm, Lie <(E-Mail Removed)> wrote:
> I'm very surprised actually, to see that Python rejected the use of
> fractional/rational numbers. However, when I read the PEP, I know
> exactly why the proposal was rejected: People compared fractions with
> integers, while it should be more fairly compared to floats.


Pretty lame reasoning, isn't it?

I use the rationals from the gmpy module very
successfully.

All these arguments that follow are just silly.

>
> Arguments against:
> - When I use the result of / as a sequence index, it's usually an
> error which should not be hidden by making the program working for
> some data, since it will break for other data.
> ----> In Python 3 (and 2 w/ __future__), the / operator would always
> return floats, and floats is invalid as sequence index, even if the
> value of the float is whole. Since fractions is created with the /
> operator on two integers, the behavior of fractions should mimics
> float. So putting fractional type as sequence index should always be
> considered as error (exception), a behavior consistent with floats.
> Thus, the arguments specified above has turned invalid, at least in
> Python 3.
> - (this assumes the same type for them Int is a good type in itself,
> not to be mixed with rationals. The fact that something is an integer
> should be expressible as a statement about its type. Many operations
> require ints and don't accept rationals. It's natural to think about
> them as about different types.
> ----> I agree, ints shouldn't be mixed with rationals. But floats
> could. This argument is the main reason why I said most people
> compared rational with integers. Many operations that requires ints
> and don't accept rationals also don't accept floats.
>
> Other arguments:
> - Slow: Doing addition and subtraction in fractions sure is expensive,
> but doing division (the heaviest arithmetic operation) is extremely
> fast in fractional numbers compared to in floating numbers. It is
> clear that doing two integer multiplication and switching numerator-
> denominator is much faster than doing a single float division.
> - Memory Intensive: To represent 1/3 to infinite accuracy requires two-
> integer-space (theoretically, 2 bytes). There are some numbers that
> are hard to represent in fractions, yes, but in general those numbers
> could be represented using two-long-space (variable-width longs). And
> whenever accuracy isn't that important, it could be possible to create
> a method that would lossily approximate the current fraction to an
> acceptable length. Anyway, most computers nowadays is packed with
> gigantic memory, why bother with such a small issue.
> - Rationals must present themselves as decimal floats or it'll be
> confusing: There will be no confusion in a good written code.
> Progammers that writes good code would always use the 'behind-the-
> scene' number, they wouldn't convert a previously 'string'ed number
> back into calculation. And a convention can be created to represent a
> fraction in a single line output (like * for multiplication, / for
> division, they don't exist in paper maths) that would completely
> eliminate any confusion of the user (well informed about the
> convention, most people that never used computer before often tried to
> use x and : to represent mult and div), even when the fractional
> number is outputted to the foreground UI.


 
Reply With Quote
 
 
 
 
Lie
Guest
Posts: n/a
 
      12-15-2007
<cont.>
The easiest implementation of using fractional datatype is probably to
add a new operator. Some scientific calculators provide a special
operator to signify a fraction (somewhat on the shape of a small L in
mine) and I strongly believe that their internal calculation probably
used fractions even when regular division is used, only when the
calculator have difficulties using fraction (like calculating sin/cos/
tan function) or the screen is not wide enough to represent the
fraction would it use regular division.

Python implemented complex numbers, why not fractions?

Random ramble past here:
Actually, my vision would be not only fractions, but also rooted
number (square root, cube root, etc), it could be possible to
implement a type where a number consist of a rooted number times a
multiplier plus a variable [a + b * root(c, d)]. But I guess this
would be extremely complex and it requires nesting, probably very slow
if implementation isn't good. The advantage of using such is much
faster operations, as long as str() is not called. This actually
reflects my way of doing paper math, I save the lossy operations
(float division, root, trigonometric function) until the very end of
calculation (I'm not fundamentalist though, so compromise sometimes is
done here and there).
 
Reply With Quote
 
Fredrik Johansson
Guest
Posts: n/a
 
      12-15-2007
On Dec 15, 2007 10:05 PM, Lie <(E-Mail Removed)> wrote:
> Random ramble past here:
> Actually, my vision would be not only fractions, but also rooted
> number (square root, cube root, etc), it could be possible to
> implement a type where a number consist of a rooted number times a
> multiplier plus a variable [a + b * root(c, d)]. But I guess this
> would be extremely complex and it requires nesting, probably very slow
> if implementation isn't good. The advantage of using such is much
> faster operations, as long as str() is not called. This actually
> reflects my way of doing paper math, I save the lossy operations
> (float division, root, trigonometric function) until the very end of
> calculation (I'm not fundamentalist though, so compromise sometimes is
> done here and there).


You're looking for a computer algebra system. Try sympy:
http://code.google.com/p/sympy/

Fredrik
 
Reply With Quote
 
Lie
Guest
Posts: n/a
 
      12-15-2007
On Dec 16, 4:55 am, "Fredrik Johansson" <(E-Mail Removed)>
wrote:
> On Dec 15, 2007 10:05 PM, Lie <(E-Mail Removed)> wrote:
>
> > Random ramble past here:
> > Actually, my vision would be not only fractions, but also rooted
> > number (square root, cube root, etc), it could be possible to
> > implement a type where a number consist of a rooted number times a
> > multiplier plus a variable [a + b * root(c, d)]. But I guess this
> > would be extremely complex and it requires nesting, probably very slow
> > if implementation isn't good. The advantage of using such is much
> > faster operations, as long as str() is not called. This actually
> > reflects my way of doing paper math, I save the lossy operations
> > (float division, root, trigonometric function) until the very end of
> > calculation (I'm not fundamentalist though, so compromise sometimes is
> > done here and there).

>
> You're looking for a computer algebra system. Try sympy:http://code.google.com/p/sympy/
>
> Fredrik


Yeah, that's why I consider them too complex for being included as a
core of a general programming language like Python. Nevertheless,
fraction datatype _IS_ elementary enough to be included as core
language feature.
 
Reply With Quote
 
Arnaud Delobelle
Guest
Posts: n/a
 
      12-15-2007
On Dec 15, 10:38 pm, Lie <(E-Mail Removed)> wrote:
[...]
>
> Yeah, that's why I consider them too complex for being included as a
> core of a general programming language like Python. Nevertheless,
> fraction datatype _IS_ elementary enough to be included as core
> language feature.


Rationals are not that simple.

* Unless you are working under very controlled conditions, rationals
very quickly grow enormous numerators and denominators, hence
require arbitrary precision integers (which, I concede, are part of
Python).

* In order to have a canonical representation of integers, they need
to be kept in normalised form.

* Nobody uses big fractions apart from mathematicians (and maybe
bookmakers?).

* Having yet another numerical type would make it difficult what
type to expect from a calculation.

--
Arnaud

 
Reply With Quote
 
greg
Guest
Posts: n/a
 
      12-15-2007
I think the main objection to rationals is that extensive
computation with them tends to result in numbers requiring
larger and larger amounts of storage. I believe that ABC
made routine use of rationals, and this caused programs
to get bogged down for no apparent reason, as rationals
were being used behind the scenes when people didn't
realise it.

So while rationals might be useful to have available for
some things, you should have to explicitly ask for them.
Returning rationals from '/' applied to integers would
be a bad idea, for example.

--
Greg
 
Reply With Quote
 
Steven D'Aprano
Guest
Posts: n/a
 
      12-16-2007
On Sat, 15 Dec 2007 15:44:26 -0800, Arnaud Delobelle wrote:

> Rationals are not that simple.
>
> * Unless you are working under very controlled conditions, rationals
> very quickly grow enormous numerators and denominators, hence require
> arbitrary precision integers (which, I concede, are part of Python).


Come now. Rationals aren't living things that grow if you sit them in the
corner and provide them air and light. Whether the numerator and
denominator grow depends on what you do with them. If you wish to say
that they *can* grow enormous numerators and denominators, I won't argue,
but implying that *must* and will *always* grow is misleading. It's pure
propaganda.

And if they do... well, longs can also "quickly grow enormous". That
hasn't stopped Python integrating ints and longs. The programmer is
expected to deal with it. Integrating floats and rationals isn't even on
the table for discussion. Anyone using rationals is making a conscious
choice to do so and can deal with the consequences.


> * In order to have a canonical representation of integers, they need to
> be kept in normalised form.


Oh noes! Not normalised form!!!

Is this supposed to be an objection?


> * Nobody uses big fractions apart from mathematicians (and maybe
> bookmakers?).


Putting the cart before the horse. Nobody uses rationals because
rationals aren't available!

Nobody uses complex numbers except for mathematicians, and maybe a few
electrical engineers, and they're a built in. Nobody uses math functions
like sin and cos except for mathematicians and engineers, and they're
available.

The Forth programming language didn't even support floating point for
many years. Programmers were expected to use the equivalent of rationals
using integers. This was very successful, and avoided the gotchas that
you get with floats. For example, with floats it is unavoidable to have
unintuitive results like (x + y) - x != y and it isn't even very hard to
find an example.

>>> 3.1 + 0.7 - 3.1 == 0.7

False

Such a bizarre result shouldn't happen with any non-buggy rational
representation:

31/10 + 7/10 - 31/10 => 38/10 - 31/10 => 7/10

In the real world, people use fractions all the time, e.g. plumbers. (Not
that I'm expecting plumbers to start taking laptops out to the building
site in order to calculate pipe sizes.)


> * Having yet another numerical type would make it difficult what type to
> expect from a calculation.


I simply don't believe that at all. It's not like calculations will
suddenly start returning rationals unexpectedly, any more than they
suddenly started returning Decimals unexpectedly.

I find it bizarre that the simple to implement, simple to understand
rational data type was rejected while the hard to implement, hard to
understand Decimal was accepted.


--
Steven
 
Reply With Quote
 
George Sakkis
Guest
Posts: n/a
 
      12-16-2007
On Dec 15, 6:52 pm, greg <(E-Mail Removed)> wrote:

> So while rationals might be useful to have available for
> some things, you should have to explicitly ask for them.
> Returning rationals from '/' applied to integers would
> be a bad idea, for example.


From my reading of the PEP, it doesn't suggest such automatic
coercions (neither rejects them explicitly though). Given the huge
discussions about integer vs true division, it would be very
controversial to suggest implicit rational division.

Regardless, a builtin (or at least standard library) rational type
would be nice to have. Of course folks that *really need* rationals
are already using some 3rd party library, but for the rest of us it
would be an improvement in several cases where currently floats are
used, just like the motivation for Decimals. Only difference seems to
be that there aren't so many or compelling use cases for rationals as
for decimals (mainly money counting).

George
 
Reply With Quote
 
Dennis Lee Bieber
Guest
Posts: n/a
 
      12-16-2007
On Sun, 16 Dec 2007 00:42:56 -0000, Steven D'Aprano
<(E-Mail Removed)> declaimed the following in
comp.lang.python:

> In the real world, people use fractions all the time, e.g. plumbers. (Not
> that I'm expecting plumbers to start taking laptops out to the building
> site in order to calculate pipe sizes.)
>

Piping tends to come in a limited range of discrete diameters, with
a slew of adapters to convert from one to another. As such, they fit
more in the Ada "fixed point" system or can be treated as a scaled
integer... One does not find random pipe diameters.
--
Wulfraed Dennis Lee Bieber KD6MOG
http://www.velocityreviews.com/forums/(E-Mail Removed) (E-Mail Removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (E-Mail Removed))
HTTP://www.bestiaria.com/
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Design of Rational number library Saeed Amrollahi C++ 8 09-07-2009 10:35 PM
Design of Rational number library Saeed Amrollahi C++ 4 09-04-2009 07:38 PM
"best" rational number library for Python? skip@pobox.com Python 7 11-01-2006 12:45 AM
OT: Number Nine, Number Nine, Number Nine FrisbeeŽ MCSE 37 09-26-2005 04:06 PM
Rational Jenny ASP .Net 1 08-22-2003 11:55 AM



Advertisments