-1

I was trying to solve Project Euler question 16 using c. I did not use bignnum libraries. The question asks 2^1000. I decided to store every digit of that number in an array.

For Example: 45 means arr[0]=4, arr[1]=5;

The problem is definitely i the function int multi.

#include<stdio.h>

#include<conio.h>
int multi(int *base, int k);// does the multiplication of array term by 2
void switcher();//switches every term when the fore mostvalue is >10
int finder();// finds the array address of last value
int arr[1000];
int summer();//sums all values of the array    

int main()
{
    arr[1000] = { 0 };
    arr[0] = 1;

    int i, j, sum, k, p;

    for (i = 0; i < 1000; i++)
    {
        j = 0;
        k = finder();
        p = multi(arr + k, j);
    }
    sum = summer();
    printf("sum of digits of 2^1000 is %d", sum);
    _getch();    
}
int multi(int *base, int k)
{       
    int p;
    if (base == arr)
    {
        *base = *base - 1;
        *base = *base + k;
        if (*base > 10)
        {
            *base = *base - 10;
            switcher();
        }
        return 0;
    }
    *base = *base * 2;
    *base = *base + k;
    if (*base > 10)
    {
        *base = *base - 10;
        p = multi(base - 1, 1);
    }
    else
    {
        p = multi(base - 1, 0);
    }    
}
void switcher()
{
    int j;

    for (j = 0;; j++)
    {
        if (arr[j] == 0)
        {
            break;
        }   
    }
    j--;
    for (; j > 0; j--)
    {
        arr[j + 1] = arr[j];
    }
    arr[0] = 1;
}
int finder()
{
    int j;
    for (j = 0;; j++)
    {
        if (arr[j] == 0)
        {
            break;
        }
    }
    return --j;
}    

int summer()
{
    int summ, i;
    summ = 0;
    for (i = 0; i<1000; i++)
    {
        summ = summ + arr[i];
        if (arr[i] == 0)
            break;
    }
    return summ;    
}

It compiles but during runtime it shows Access Write Violation, base was ......

Please explain this error and how to resolve it ?

ArK
  • 20,698
  • 67
  • 109
  • 136
Sashurocks
  • 11
  • 4
  • your array is sized by 100, but you're looping up to 1000 in some function... – Jean-François Fabre Nov 02 '16 at 09:11
  • That should be fine since 2^1000 is less than 100 digits – Sashurocks Nov 02 '16 at 09:13
  • 3
    2^1000 has 302 decimal digits. And the last valid index of an array with K elements is K - 1. (`arr[100] = { 0 };` assigns zero to the non-existing hundredth element, it does not fill the array with zero.) – molbdnilo Nov 02 '16 at 09:13
  • http://stackoverflow.com/questions/201101/how-to-initialize-all-members-of-an-array-to-the-same-value i followed what was written in the link, even after changing to 1000 i get an error – Sashurocks Nov 02 '16 at 09:26
  • 1
    @Sashurocks That question is about *initialization*. `arr[100] = {0};` is not an array initialization, it's an assignment. It's exactly equivalent to `arr[100] = 0;`. – molbdnilo Nov 02 '16 at 09:35

2 Answers2

0

Array is of 100 Bytes but you are looping for 1000. Also in function Finder() , you do not have a limit on variable j so your array size is going beyond 100 bytes.

Also use memset to assign array variables to 0.

Dheeraj Kumar
  • 377
  • 2
  • 13
0

As said in the comments, 2^1000 has 302 decimal digits.
You're going far outside your array.

But your code is very complicated because you store the digits with the most significant one first.
Since you're only interested in the digits and not the order in which they would be written, you can store the number "in reverse", with the least significant digit first.
This makes the code much simpler, as you can loop "forwards" and no longer need to shuffle array elements around.

Using -1 as "end of number" marker, it might look like this:

void twice(int* digits)
{
    int i = 0;
    int carry = 0;
    while (digits[i] >= 0)
    {
        digits[i] *= 2;
        digits[i] += carry;
        if (digits[i] >= 10)
        {
            carry = 1;
            digits[i] -= 10;
        }
        else
        {
            carry = 0;
        }
        i++;
    }
    if (carry)
    {
        digits[i] = 1;
        digits[i+1] = -1;
    }
}

int main()
{
    int digits[302] = {1, -1}; /* Start with 1 */
    twice(digits);           /* digits is now { 2, -1 } */
    return 0;
}
molbdnilo
  • 64,751
  • 3
  • 43
  • 82