2
import math

def sumOfDigit(num):
    sum_of_digits = 0
    while num > 9:
        sum_of_digits += num % 10
        num = int(num/10)
    sum_of_digits += num
    return sum_of_digits

print sumOfDigit(math.pow(2,1000))

This is what I thought of for Project Euler #16, and it works fine for smaller numbers. But when I tried 21000, the code gave me 1289.0 instead of the answer 1366 (Found this on the internet). I think the problem might have to do with the size of the number, but I'm not sure. Any points in the right direction will be appreciated. Thanks in advance!

Edit: Here is the question https://projecteuler.net/problem=16

1
  • 2
    Please include what you are trying to achieve in the question, not as an external link. Commented Jul 26, 2017 at 8:34

4 Answers 4

5

The reason is that math.pow(2,1000) returns a float and not an int. Therefore, the operation num/10 returns a different answer than expected.

When calling with 2 ** 1000 the expected answer is returned.

Edit: in case of python 3, please note Hans comment or tobias_k answer regarding integers division.

Sign up to request clarification or add additional context in comments.

1 Comment

With a Python 3.5.2, I just got the same problem even when using 2**1000 as the argument; I had to - additionally - use floor division in the reduction step to get the right result: num = num//10
1

The problem is that math.pow returns a floating point number, and for that large a number, the floating point precision is not good enough to give you a precise answer. Change your function like this:

def sumOfDigit(num):
    sum_of_digits = 0
    while num > 9:
        sum_of_digits += num % 10
        num = num // 10  # use integer division // instead of /
    sum_of_digits += num
    return sum_of_digits

print(sumOfDigit(pow(2, 1000))) # use builtin pow or ** operator instead of math.pow

Or shorter:

print(sum(int(c) for c in str(2**1000)))

Comments

0

I'd say that your number calculation is simply wrong. It can be achieved much easier:

import math

number = str(int(math.pow(2,1000)))
total = 0

for i in number:
    total += int(i)

print(total) #1366

Simply calculate the result of 21000, convert it to str and go through the numbers to sum them up.

4 Comments

Unexpectedly, this works. I don't understand how int(math.pow(2, 1000)) could find all the digits as math.pow(2, 1000) is a float. Do you have an explanation ?
@Gribouillis Might have something to do that it's a power of two and thus can be represented exactly even as a floating point number.
@tobias_k Indeed the ieee754 representation of 2**1000 on 64 bits is 0 11111100111 0000000000000000000000000000000000000000000000000000. All the information is in the exponent. It is an exact number.
As Elisha notes, the problem is not strictly the floating point representation of math.pow, but the division by 10 in the loop which gets a wrong result on the float.
0

Without math module, basically can be done like this:

a=list(str(2**1000))
b=0
for i in range(0,len(a)):
b+=int(a[i])
print(b)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.