storing more than 2 power 31 on a 32-bit system

前端 未结 6 657
别那么骄傲
别那么骄傲 2020-12-09 05:17

I have to write a program that can calculate the powers of 2 power 2010 and to find the sum of the digits. eg:

if `2 power 12 => gives 4096          


        
相关标签:
6条回答
  • 2020-12-09 05:19

    This takes only a few lines of code in Delphi... :)

    So in c must be the same or shorter.

    function PowerOf2(exp: integer): string;
    var
      n     : integer;
      Digit : integer;
    begin
      result := '1';
      while exp <> 0 do
      begin
        Digit := 0;
        for n := Length(result) downto 1 do
        begin
          Digit := (ord(result[n]) - ord('0')) * 2 + Digit div 10;
          result[n] := char(Digit mod 10 + ord('0'))
        end;
        if Digit > 9 then
          result := '1' + result;
        dec(exp);
      end;
    end;
    

    -----EDIT-----

    This is 1-to-1 c# version.

    string PowerOf2(int exp)
    {
        int n, digit;
        StringBuilder result = new StringBuilder("1");
        while (exp != 0)
        {
            digit = 0;
            for (n = result.Length; n >= 1; n--)
            {
                digit = (result[n-1] - '0') * 2 + digit / 10;
                result[n-1] = Convert.ToChar(digit % 10 + '0');
            }
            if (digit > 9)
            {
                result = new StringBuilder("1" + result.ToString());
            }
            exp--;
        }
        return result.ToString();
    }
    
    int Sum(string s)
    {
        int sum = 0;
        for (int i = 0; i < s.Length; i++)
        {
            sum += s[i] - '0';
        }
        return sum;
    }
    
    for (int i = 1; i < 20; i++)
    {
        string s1s = PowerOf2(i);
        int sum = Sum(s1s);
         Console.WriteLine(s1s + " --> " + sum);
    }
    
    0 讨论(0)
  • 2020-12-09 05:21

    Here's how you can calculate and print 22010:

    #include <stdio.h>
    #include <string.h>
    
    void AddNumbers(char* dst, const char* src)
    {
      char ddigit;
      char carry = 0;
    
      while ((ddigit = *dst) != '\0')
      {
        char sdigit = '0';
    
        if (*src != '\0')
        {
          sdigit = *src++;
        }
    
        ddigit += sdigit - '0' + carry;
    
        if (ddigit > '9')
        {
          ddigit -= 10;
          carry = 1;
        }
        else
        {
          carry = 0;
        }
    
        *dst++ = ddigit;
      }
    }
    
    void ReverseString(char* s)
    {
      size_t i, n = strlen(s);
    
      for (i = 0; i < n / 2; i++)
      {
        char t = s[i];
        s[i] = s[n - 1 - i];
        s[n - 1 - i] = t;
      }
    }
    
    int main(void)
    {
      char result[607], tmp[sizeof(result)];
      int i;
    
      memset (result, '0', sizeof(result));
      result[0] = '1';
      result[sizeof(result) - 1] = '\0';
    
      for (i = 0; i < 2010; i++)
      {
        memcpy(tmp, result, sizeof(result));
        AddNumbers(result, tmp);
      }
    
      ReverseString(result);
      printf("%s\n", result);
    
      return 0;
    }
    

    You can now sum up the individual digits.

    0 讨论(0)
  • 2020-12-09 05:22

    Here's something to get you started:

    char buf[2010]; // 2^2010 < 10^2010 by a huge margin, so buffer size is safe
    snprintf(buf, sizeof buf, "%.0Lf", 0x1p2010L);
    
    0 讨论(0)
  • 2020-12-09 05:22

    Knowing 2^32, how would you calculate 2^33 with pen and paper?

    2^32 is 4294967296
    
    4294967296
    *        2
    ----------
    8589934592
    
    8589934592 is 2^33; sum of digits is 8+5+8+9+...+9+2 (62)
    

    Just be aware that 2^2011 is a number with more than 600 digits: not that many to do by computer

    0 讨论(0)
  • 2020-12-09 05:28

    You have to either use a library that supplies unlimited integer length types (see http://en.wikipedia.org/wiki/Bignum ), or implement a solution that does not need them (e.g. use a digit array and implement the power calculation on the array yourself, which in your case can be as simple as addition in a loop). Since this is homework, probably the latter.

    0 讨论(0)
  • 2020-12-09 05:46

    GMP is perhaps the best, fastest free multi-architecture library for this. It provides a solid foundation for such calculations, including not only addition, but parsing from strings, multiplication, division, scientific operations, etc.

    For literature on the algorithms themselves, I highly recommend The Art of Computer Programming, Volume 2: Seminumerical Algorithms by Donald Knuth. This book is considered by many to be the best single reference for the topic. This book explains from the ground up how such arithmetic can take place on a machine that can only do 32-bit arithmetic.

    If you want to implement this calculation from scratch without using any tools, the following code block requires requires only the following additional methods to be supplied:

    unsigned int divModByTen(unsigned int *num, unsigned int length);
    bool isZero(unsigned int *num, unsigned int length);
    

    divModByTen should divide replace num in memory with the value of num / 10, and return the remainder. The implementation will take some effort, unless a library is used. isZero just checks if the number is all zero's in memory. Once we have these, we can use the following code sample:

    unsigned int div10;
    int decimalDigitSum;
    
    unsigned int hugeNumber[64];
    memset(twoPow2010, 0, sizeof(twoPow2010));
    twoPow2010[63] = 0x4000000;
    // at this point, twoPow2010 is 2^2010 encoded in binary stored in memory
    
    decimalDigitSum = 0;
    while (!izZero(hugeNumber, 64)) {
        mod10 = divModByTen(&hugeNumber[0], 64);
        decimalDigitSum += mod10;
    }
    
    printf("Digit Sum:%d", decimalDigitSum);
    
    0 讨论(0)
提交回复
热议问题