Using fractions instead of floats
mensanator at aol.com
mensanator at aol.com
Mon Oct 1 20:58:07 EDT 2007
On Oct 1, 7:09 pm, andresj <andres.j.... at gmail.com> wrote:
> > > On 2007-10-01, Arnaud Delobelle <arno... at googlemail.com> wrote:
>
> > > > Finally, arithmetic would become very confusing if there were
> > > > three distinct numeric types; it already causes enough
> > > > confusion with two!
>
> Well, yeah... I get what you are saying, that would be confusing...
>
> Terry Reedy and Laurent Pointal:
> I know from __future__ import division changes the behaivour to return
> floats instead of ints, but what I meant is to be able to implement a
> function (or class/method) which would return what _I_ want/decide.
>
> Gabriel Genellina, thanks for the suggestion of wrapping my code. I
> think it could be one way... But I think it would be too much trouble,
> I'll just go with writing fractions/rationals explicitly.
>
> And thanks to mensanator and Gabriel for the suggestion of gmpy, and
> to Nick for the example (It really helps to have an example,
Would you like to see a more thorough example?
First, go check out the Wikipedia article:
<http://en.wikipedia.org/wiki/Collatz_conjecture>
And scroll down the the section "Iterating on rational numbers
with odd denominators". I added the section beginning with
"The complete cycle being:..." through "And this is because...".
Here's the Python program I used to develop that section.
import gmpy
def calc_pv_xyz(pv):
"""calculate Hailstone Function Parameters
using Parity Vector instead of Sequence Vector
(defined using (3n+1)/2)
calc_pv_xyz(pv)
pv: parity vector
returns HailstoneFunctionParameters (x,y,z)
"""
ONE = gmpy.mpz(1)
TWO = gmpy.mpz(2)
TWE = gmpy.mpz(3)
twee = gmpy.mpz(sum(pv))
twoo = gmpy.mpz(len(pv))
x = TWO**twoo
y = TWE**twee
z = gmpy.mpz(0)
c = gmpy.mpz(sum(pv)-1)
for i,j in enumerate(pv):
if j:
z += TWE**c * TWO**i
c -= ONE
return (x,y,z)
def iterating_on_rational(n): # Collatz for rational numbers
# is numerator odd?
if n.numer() % 2 == 1:
n = (n*3 + 1)/2
else:
n = n/2
print n,
return n
pv = [1,0,1,1,0,0,1]
for i in xrange(len(pv)+1):
print pv
# get Hailstone Function parameters X,Y,Z
xyz = calc_pv_xyz(pv)
# calculate the Crossover Point Z/(X-Y)
cp = gmpy.mpq(xyz[2],xyz[0]-xyz[1]) # as a rational number
# start of loop cycle
print cp,
# start the cycle...
n = iterating_on_rational(cp)
# ...which MUST return to the starting point
# since ALL rationals are valid Crossover Points
# not just integers
while n != cp:
n = iterating_on_rational(n)
print
print
# step through the cyclic permutations
p = pv.pop(0)
pv.append(p)
## parity vector cyclic permutations
##
## [1, 0, 1, 1, 0, 0, 1]
## 151/47 250/47 125/47 211/47 340/47 170/47 85/47 151/47
##
## [0, 1, 1, 0, 0, 1, 1]
## 250/47 125/47 211/47 340/47 170/47 85/47 151/47 250/47
##
## [1, 1, 0, 0, 1, 1, 0]
## 125/47 211/47 340/47 170/47 85/47 151/47 250/47 125/47
##
## [1, 0, 0, 1, 1, 0, 1]
## 211/47 340/47 170/47 85/47 151/47 250/47 125/47 211/47
##
## [0, 0, 1, 1, 0, 1, 1]
## 340/47 170/47 85/47 151/47 250/47 125/47 211/47 340/47
##
## [0, 1, 1, 0, 1, 1, 0]
## 170/47 85/47 151/47 250/47 125/47 211/47 340/47 170/47
##
## [1, 1, 0, 1, 1, 0, 0]
## 85/47 151/47 250/47 125/47 211/47 340/47 170/47 85/47
##
## [1, 0, 1, 1, 0, 0, 1]
## 151/47 250/47 125/47 211/47 340/47 170/47 85/47 151/47
> because
> it usually takes me hours to get to what I want in the
> documentations :). I think I will use that, when i get it working in
> Ubuntu. Do you guys know of any pre-made package or guides for getting
> it working in Ubuntu?
>
> Well, I guess my idea was not as good as I thought it was :). But
> anyways... I look forward to Python 3.0 (Specially the
> __future__.with_statement and the standardization of names-- cStringIO
> is just too ugly for my eyes!)
More information about the Python-list
mailing list