2

I'm completing the 56th question on Project Euler:

A googol (10100) is a massive number: one followed by one-hundred zeros; 100100 is almost unimaginably large: one followed by two-hundred zeros. Despite their size, the sum of the digits in each number is only 1.

Considering natural numbers of the form, ab, where a, b < 100`, what is the maximum digital sum?

I wrote this code, which gives the wrong answer:

import math

value = 0
a = 1
b = 1


while a < 100:
    b = 1
    while b < 100:
        result = int(math.pow(a,b))
        x = [int(a) for a in str(result)]
        if sum(x) > value:
            value = sum(x)
        b = b + 1
    a = a + 1

print(value)

input("")

My code outputs 978, whereas the correct answer is

972

I already know the actual approach, but I don't know why my reasoning is incorrect. The value that gives me the greatest digital sum seems to be 8899, but adding together each digit in that result will give me 978. What am I misinterpreting in the question?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
  • 1
    Welcome to Stack Overflow. When you have code that runs without errors but gives the wrong output (and you know what the correct output is, and how it should be calculated) the next step is to try to figure out where the code diverges from the expected behaviour. See https://ericlippert.com/2014/03/05/how-to-debug-small-programs/ for details. It is also useful to understand the fundamentals of the language you are using. I don't know how you learned about `math.pow` existing, but any good tutorial should have shown **first** you that `88 ** 99` works fine, as Python `int` are arbitrary size. – Karl Knechtel May 23 '22 at 01:49
  • See also: https://stackoverflow.com/questions/588004/is-floating-point-math-broken. I don't think this question can be considered a duplicate, as you presumably didn't *expect* to be using floating-point math. – Karl Knechtel May 23 '22 at 01:54

1 Answers1

4

math.pow uses floating point numbers internally:

Unlike the built-in ** operator, math.pow() converts both its arguments to type float.

Note that Python integers have no size restriction, so there is no problem computing 88 ** 99 this way:

>>> from math import pow
>>> pow(88, 99)
3.1899548991064687e+192
>>> 88**99
3189954899106468738519431331435374548486457306565071277011188404860475359372836550565046276541670202826515718633320519821593616663471686151960018780508843851702573924250277584030257178740785152

And indeed, this is exactly what the documentation recommends:

Use ** or the built-in pow() function for computing exact integer powers.

The result computed using math.pow will be slightly different, due to the lack of precision of floating-point values:

>>> int(pow(88, 99))
3189954899106468677983468001676918389478607432406058411199358053788184470654582587122118156926366989707830958889227847846886750593566290713618113587727930256898153980172821794148406939795587072

It so happens that the sum of these digits is 978.

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Grismar
  • 27,561
  • 4
  • 31
  • 54
  • 1
    FWIW you can just use the built-in [`pow()`](https://docs.python.org/3/library/functions.html#pow) instead of `math.pow`. – Mark May 23 '22 at 01:49
  • 1
    Good answer, but no need to speculate with "appears to be using floating point numbers" - the documentation for `math.pow` is very clear and would be helpful to cite. https://docs.python.org/3/library/math.html#math.pow – Weeble May 23 '22 at 02:03
  • 2
    I edited to address the concern about the documentation, and realized about the built-in `pow` in passing. I think this version covers everything now. – Karl Knechtel May 23 '22 at 02:05