2

First off all, thanks for the attention, I'm new to this site ^^ so excuse me if I do something wrong...

I have a huge problem with my Python code... I'm new to programming, and I'm new to Python as well.

I need to take a floating point number and move the point right so it becomes an integer, like taking 60.27 and getting 6027.

The algorithm that I'm using is recursively multiplying num*10 until num%2==0, then getting the int(num).

The problem is, when I multiply (for example) 602.47*10 it returns 6024.700000000001 and it obviously doesn't work :-)

Is there any way to fix it, or any other technique or other way to do this recursively?? I'm allowed to use anything I need, but its got to be recursive: no for or while...

Thanks for the help!! My first language is not english, so I beg your pardon if it's hard to read...

mskfisher
  • 3,291
  • 4
  • 35
  • 48
dhcarmona
  • 402
  • 2
  • 10
  • 29

6 Answers6

2

Floating point representations have that issue.

Are you looking to change:

1.2345
12.345
123.45
1234.5

all to 12345?

For floats which have no exact representation (you mention 6024.70), do you expect to get 6024700000000001, since that's the output of the closest thing to 6024.70 which can be stored in float?

Cade Roux
  • 88,164
  • 40
  • 182
  • 265
  • That's exactly the problem that I had ^^, as other suggested I parsed it as a str and simply removed the floating point... Thanks! – dhcarmona Apr 04 '11 at 16:44
2
>>> str(60.27).translate(None, '.')
'6027'

Use lstrip('0') to guard against decimals below 1.


From the docs:

S.translate(table [,deletechars]) -> string

Return a copy of the string S, where all characters occurring in the optional argument deletechars are removed, and the remaining characters have been mapped through the given translation table, which must be a string of length 256.

N 1.1
  • 12,418
  • 6
  • 43
  • 61
1

It would be more reliable an algorithm to just parse the number as a string and do a string manipulation. Any numerical calculation involving floating-point numbers are bound to inaccuracy, as you've witnessed. There's no going around that.

Santa
  • 11,381
  • 8
  • 51
  • 64
  • Thanks for the help ^^ that is what I ended up using, parsing the number as a str and using .replace, as others suggested... Thanks! – dhcarmona Apr 04 '11 at 16:40
1

Since you can't (reliably) use floating point to do what you want, an easy hack is to convert the number to a string then rip out the decimal point:

int(str(num).replace('.',''))

That will work with any number that isn't represented in scientific notation. If your numbers are big (or small) enough that they do end up represented in scientific notation, have a look at this.

Community
  • 1
  • 1
nmichaels
  • 49,466
  • 12
  • 107
  • 135
1

You could try something like:

x = 60.27
newx = int(str(x).replace('.',''))

Edit: as a side note, the string .replace and .translate have similar performance for various sized floats

%timeit int(str(4.73285).replace('.',''))
100000 loops, best of 3: 2.65 us per loop

%timeit int(str(4.73285).translate(None, '.'))
100000 loops, best of 3: 3.02 us per loop
JoshAdel
  • 66,734
  • 27
  • 141
  • 140
1

Just taking a wild stab in the dark here, but do your numbers represent amounts of money that you're trying to convert between (say) dollars and cents? If so, you need to stop what you are doing and convert everything to cents, and only use "dollar" values when actually presenting things to the user. Using floating point numbers for money values is a very, very bad idea.

If not, ignore me :-)

regularfry
  • 3,248
  • 2
  • 21
  • 27
  • Thanks for the help... Actually, what I needen to do was to validate a floating point number to a certain base, say: validating 11.1112 to base 2 would be False, for example... – dhcarmona Apr 04 '11 at 16:41