Frank Li
Frank Li

Reputation: 55

matlab precision dealing with big number

The question encountered me when I was trying to solve Project Euler #16.

The problem reads:

215 = 32768 and the sum of its digits is 3 + 2 + 7 + 6 + 8 = 26.

What is the sum of the digits of the number 21000?

I was trying to deal with it with MATLAB. Here's my code:

function [sum] = power_digit_sum_p16(pow)
    sum = 0;
    n = 2 ^ pow;
    M = zeros(1,301);
    for i = 301 : -1 : 0
        a = floor(n / 10 ^ i);
        M(302 - i) = a;
        sum = sum + a;
        n = n - 10 ^ i * a;
    end
end

(Where the 301 stands for 301 digits of 2^1000)

When I ran pow_digit_sum_p16(1000), MATLAB returned 1285, which is wrong.

Then I checked the number provided by MATLAB, which is stored in matrix M, when I learned that something is wrong.

The last digit of 2^1000 should be 6 instead of 2 (it follows a 2-4-8-6-2-4-8-6 pattern)! I don't understand what's going on here with MATLAB, but I guess the problem occurred because the number is too big, since my function works fine when pow is small.

My friend provided me with a Python solution, and it seems that python handles the big number well. Below is the code in Python:

x=2**1000
ans=0
while x>0:
    ans+=(x%10)
    x=x//10
print(ans)

Update: thanks to OmG's answer, I changed my code a little bit:

function [sum] = power_digit_sum_p16(pow)
    sum = 0;
    n = 2 ^ pow;
    n = sym(n);                     % This line is new!
    M = zeros(1,301);
    for i = 301 : -1 : 0
        a = floor(n / (10 ^ i));
        M(302 - i) = a;
        sum = sum + a;
        n = n - (10 ^ i) * a;
    end
end

And I got what I expected. Note that the sym function needs the Symbolic Math Toolbox.

Upvotes: 1

Views: 154

Answers (1)

OmG
OmG

Reputation: 18838

A solution is using symbolic tools. For example for finding the true value for the remaining for 2^1000 over 10 you can do it likes the following:

x = sym('2^1000');
reminder = fix(double(mod(x,10)))

The answer is:

 reminder = 
 6

For 100 and 1000 is 67 and 376 respectively.

Upvotes: 1

Related Questions