padrezulmiro
padrezulmiro

Reputation: 47

Unexpected behaviour parsing integer to string

While trying to solve a checkio exercise I stumbled into a strange behaviour.

def friendly_number(number, base=1000, decimals=0, suffix='',
            powers=['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']):
    power_i = 0    
    while abs(number) >= base and power_i < len(powers)-1:
        number /= base
        power_i += 1

    number_str = str(number)

    return number_str

fn = friendly_number(10**32)

I was expecting fn == "100000000", but I got fn = "99999999.99999999". I narrowed it down to the step number_str = str(number). The strangest bit was testing this on the command line: when I did that the value returned was "100000000". What is happening here?

Upvotes: 1

Views: 72

Answers (2)

Chris
Chris

Reputation: 22953

In Python 3 there are two types of division, floating-point and true division. floating-point division will yield a float, while true division will round the float to the nearest whole number and return an integer:

>>> 1 / 1 # floating-point division
1.0
>>> 1 // 1 # true division
1
>>> 

In your case, you're using the in-place floating point division operator, /=. You need to use the in-place true division operator:

number //= base

With the change above the value of fn is the expected result, 100000000:

>>> fn = friendly_number(10**32)
>>> fn
'100000000'
>>>

Upvotes: 3

AGN Gazer
AGN Gazer

Reputation: 8378

In Python 3 use:

number //= base

Your current statement (number /= base) should work fine in Python 2.

Upvotes: 1

Related Questions