-3

Is there any data type that is capable of storing values within range 0<X<10^20 in c/c++??

ranger101
  • 1,184
  • 4
  • 12
  • 20

6 Answers6

12

Since log2(10^20) = ~66.43 you will need an integer made by 128 bits to store the number with integer precision. Actually, as pointed out by delnan in comment, 67 bits would be sufficient, by rounding to 72 bits with 8 bits alignment or 96 bits with 32 bits alignment.

So, if you don't require an exact integer representation, you could use a float or a double, otherwise you could look for a arbitrary long number library (there are many available either for C or C++).

Jack
  • 131,802
  • 30
  • 241
  • 343
  • To nitpick, 67 bits are sufficient. More realistically, you might round up to 72 bit (9 bytes) if space is premium, or 96 bit (12 byte) for 32 bit alignment. –  Jul 23 '13 at 16:15
  • Yes, I was talking about "standard" size for integer types which usually just get twice the number of bits. Let me specify it. – Jack Jul 23 '13 at 16:16
  • Why is it that ~2x the minimum bits are required to get integer precision? – Alexander Christiansson Jul 23 '13 at 16:19
  • 1
    @AlexanderChristiansson the existing integral types are commonly 8-16-32-64 bits long so the next step in that series would be 128, twice 64. – fvu Jul 23 '13 at 16:20
9

A float and a double can store values in the range you have specified, and beyond.

Note that it cannot store the precise discrete integers in that range, merely an approximation that is often relevant to the order of magnitude.

Brian Cain
  • 14,403
  • 3
  • 50
  • 88
2

Both float and double can store numbers of range at least 1E-37 to 1E+37.

If you need exact precision, you can use a big num library like GMP.

ouah
  • 142,963
  • 15
  • 272
  • 331
  • This shortchanges the ranges of `float` and `double` by an infinite amount, since their actual ranges (with IEEE 754) are from –∞ to +∞. – Eric Postpischil Jul 23 '13 at 16:59
  • @EricPostpischil Here I refer to C requirements for minimum max value and maximum min value. But assuming `float` is `binary32` IEEE 754 type, the range is from `~ 1.18 × 10^−38` to `~ 3.4 × 10^38` according to http://en.wikipedia.org/wiki/Single-precision_floating-point_format Do I miss something? – ouah Jul 23 '13 at 17:29
  • The Wikipedia page is wrong. It notes that infinity can be encoded with an exponent of 0xff (for 32-bit floating-point) but also says the maximum representable value is about 3.4e38. Obviously infinity is greater than 3.4e38. Since both –∞ and +∞ are representable, the range of representable values is –∞ to +∞. – Eric Postpischil Jul 23 '13 at 17:34
  • @EricPostpischil and what about the range between 3.4e38 to –∞? If you cannot represent numbers in that range, you cannot say the range is –∞ to +∞. – ouah Jul 23 '13 at 17:52
  • 1
    What about the range between the largest representable finite value and the second largest? That is a span of 20,282,409,603,651,670,423,947,251,286,016. By your reasoning, if you cannot represent numbers in that range, you cannot say the range is –340282346638528859811704183484516925440 to +340282346638528859811704183484516925440. Continuing in that way implies that no representation is possible if it uses discrete values. – Eric Postpischil Jul 23 '13 at 17:59
2

float or double can store the range you desire. You can also use a Big Integer library. Here's an example:

// header files

#include <cstdio>
#include <string>
#include <algorithm>
#include <iostream>

using namespace std;

struct Bigint {
    // representations and structures
    string a; // to store the digits
    int sign; // sign = -1 for negative numbers, sign = 1 otherwise

    // constructors
    Bigint() {} // default constructor
    Bigint( string b ) { (*this) = b; } // constructor for string

    // some helpful methods
    int size() { // returns number of digits
        return a.size();
    }
    Bigint inverseSign() { // changes the sign
        sign *= -1;
        return (*this);
    }
    Bigint normalize( int newSign ) { // removes leading 0, fixes sign
        for( int i = a.size() - 1; i > 0 && a[i] == '0'; i-- )
            a.erase(a.begin() + i);
        sign = ( a.size() == 1 && a[0] == '0' ) ? 1 : newSign;
        return (*this);
    }

    // assignment operator
    void operator = ( string b ) { // assigns a string to Bigint
        a = b[0] == '-' ? b.substr(1) : b;
        reverse( a.begin(), a.end() );
        this->normalize( b[0] == '-' ? -1 : 1 );
    }

    // conditional operators
    bool operator < ( const Bigint &b ) const { // less than operator
        if( sign != b.sign ) return sign < b.sign;
        if( a.size() != b.a.size() )
            return sign == 1 ? a.size() < b.a.size() : a.size() > b.a.size();
        for( int i = a.size() - 1; i >= 0; i-- ) if( a[i] != b.a[i] )
            return sign == 1 ? a[i] < b.a[i] : a[i] > b.a[i];
        return false;
    }
    bool operator == ( const Bigint &b ) const { // operator for equality
        return a == b.a && sign == b.sign;
    }



    // mathematical operators
    Bigint operator + ( Bigint b ) { // addition operator overloading
        if( sign != b.sign ) return (*this) - b.inverseSign();
        Bigint c;
        for(int i = 0, carry = 0; i<a.size() || i<b.size() || carry; i++ ) {
            carry+=(i<a.size() ? a[i]-48 : 0)+(i<b.a.size() ? b.a[i]-48 : 0);
            c.a += (carry % 10 + 48);
            carry /= 10;
        }
        return c.normalize(sign);
    }
    Bigint operator - ( Bigint b ) { // subtraction operator overloading
        if( sign != b.sign ) return (*this) + b.inverseSign();
        int s = sign; sign = b.sign = 1;
        if( (*this) < b ) return ((b - (*this)).inverseSign()).normalize(-s);
        Bigint c;
        for( int i = 0, borrow = 0; i < a.size(); i++ ) {
            borrow = a[i] - borrow - (i < b.size() ? b.a[i] : 48);
            c.a += borrow >= 0 ? borrow + 48 : borrow + 58;
            borrow = borrow >= 0 ? 0 : 1;
        }
        return c.normalize(s);
    }
    Bigint operator * ( Bigint b ) { // multiplication operator overloading
        Bigint c("0");
        for( int i = 0, k = a[i] - 48; i < a.size(); i++, k = a[i] - 48 ) {
            while(k--) c = c + b; // ith digit is k, so, we add k times
            b.a.insert(b.a.begin(), '0'); // multiplied by 10
        }
        return c.normalize(sign * b.sign);
    }
    Bigint operator / ( Bigint b ) { // division operator overloading
        if( b.size() == 1 && b.a[0] == '0' ) b.a[0] /= ( b.a[0] - 48 );
        Bigint c("0"), d;
        for( int j = 0; j < a.size(); j++ ) d.a += "0";
        int dSign = sign * b.sign; b.sign = 1;
        for( int i = a.size() - 1; i >= 0; i-- ) {
            c.a.insert( c.a.begin(), '0');
            c = c + a.substr( i, 1 );
            while( !( c < b ) ) c = c - b, d.a[i]++;
        }
        return d.normalize(dSign);
    }
    Bigint operator % ( Bigint b ) { // modulo operator overloading
        if( b.size() == 1 && b.a[0] == '0' ) b.a[0] /= ( b.a[0] - 48 );
        Bigint c("0");
        b.sign = 1;
        for( int i = a.size() - 1; i >= 0; i-- ) {
            c.a.insert( c.a.begin(), '0');
            c = c + a.substr( i, 1 );
            while( !( c < b ) ) c = c - b;
        }
        return c.normalize(sign);
    }



    // output method
    void print() {
        if( sign == -1 ) putchar('-');
        for( int i = a.size() - 1; i >= 0; i-- ) putchar(a[i]);
    }
};

int main() {
    Bigint a, b, c; // declared some Bigint variables

    /////////////////////////
    // taking Bigint input //
    /////////////////////////
    string input; // string to take input

    cin >> input; // take the Big integer as string
    a = input; // assign the string to Bigint a

    cin >> input; // take the Big integer as string
    b = input; // assign the string to Bigint b

    //////////////////////////////////
    // Using mathematical operators //
    //////////////////////////////////

    c = a + b; // adding a and b
    c.print(); // printing the Bigint
    puts(""); // newline

    c = a - b; // subtracting b from a
    c.print(); // printing the Bigint
    puts(""); // newline

    c = a * b; // multiplying a and b
    c.print(); // printing the Bigint
    puts(""); // newline

    c = a / b; // dividing a by b
    c.print(); // printing the Bigint
    puts(""); // newline

    c = a % b; // a modulo b
    c.print(); // printing the Bigint
    puts(""); // newline

    /////////////////////////////////
    // Using conditional operators //
    /////////////////////////////////

    if( a == b ) puts("equal"); // checking equality
    else puts("not equal");

    if( a < b ) puts("a is smaller than b"); // checking less than operator

    return 0;
}

I collect this sample library from here. Maybe it will help you to build your own.

The Amateur Coder
  • 789
  • 3
  • 11
  • 33
lukai
  • 536
  • 1
  • 5
  • 20
1

The double type can hold some values up to that range, but it can't represent all integers in that range (because as noted in one of the other answers, you would need 67 bits to represent all such integers while a double has only 52 bits of mantissa).

Mark B
  • 95,107
  • 10
  • 109
  • 188
1

http://msdn.microsoft.com/en-us/library/s3f49ktz(v=vs.80).aspx

float and double data types would be the answer. But moreover I think DOUBLE data type is ideal.

chinthana
  • 183
  • 1
  • 3
  • 9