mercredi 17 juin 2015

Why does Python 3.x mess up float multiplication and how do I fix it? [duplicate]

This question already has an answer here:

I'm trying to play with some crypto algorithms and I want to make a random number generator. I know they exist out there and I can find them online, but I like the low level stuff and playing with numbers and trying to code the math myself, or at least as much of it as I can understand.

Anyway, here's my problem

from random import random

x = random()

x will have some value like .123456789

What I want to do is basically just get rid of the decimal point. I want to change .123456789 to 123456789

The algorithm that seems to make the most sense to me is just keep multiplying by ten until you reach an integer number (which will still be a float type in Python like 123456789.0 but that's easily fixable).

Here's the algorithm I'm using:

while x - math.floor(x) > 0:
    x = x * 10

This seems to make sense in my head, and usually seems to start to work for a few iterations (depending on the number). For example, with this specific number .123456789, the first iteration works fine.

x = 0.123456789
math.floor(x) = 0
x - math.floor(x) = 0.123456789
x * 10 = 1.23456789

The second iteration is still fine, though something funky happens with the floor function:

x = 1.23456789
math.floor(x) = 1
x - math.floor(x) = 0.2345678899999999
x * 10 = 12.3456789

The third iteration, however, produces this:

x = 12.3456789
math.floor(x) = 12
x - math.floor(x) = 0.34567889999999935
x * 10 = 123.45678899999999

Even in the Python shell if you do 12.3456789 - 12 you get 0.34567889999999935. So it's not a problem with the floor function (which wouldn't be a problem anyway because I'm not using the result of that for anything other than a conditional check). Likewise, performing 12.3456789 * 10 in the Python shell yields 123.45678899999999.

This isn't necessarily a problem, because I'm still getting what look like random numbers:

Random x: 0.42897433925277917
Result:     428974339252779

Random x: 0.7743038325345983
Result:     7743038325345982

Random x: 0.8341706313818842
Result:     8341706313818842

Random x: 0.4544050222261581
Result:     4544050222261581

Random x: 0.754696159031209
Result:     7546961590312095

I'm just more curious what I'm overlooking.

In case anyone is wondering, here is the full code (I'm using Python3.4):

import random
import math

x = random.SystemRandom().random()
#print('Random x:', x) #output

while x - math.floor(x) > 0:
    x = x * 10

x = (int)(x)
#print("Result:    ", x) #output




Aucun commentaire:

Enregistrer un commentaire