在 C/C++ 中存储值 <=10^20 的数据类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17815477/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:27:57  来源:igfitidea点击:

Data type to store value <=10^20 in C/C++

c++c

提问by Jijo Jose

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

是否有任何数据类型能够在 c/c++中存储 0< X<10^20范围内的值??

回答by Hyman

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

因为log2(10^20) = ~66.43您将需要一个由128位组成的整数来存储具有整数精度的数字。实际上,正如 delnan 在评论中指出的那样67,通过舍入为72具有 8 位对齐的96位或具有 32 位对齐的位,位就足够了。

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

因此,如果您不需要精确的整数表示,则可以使用 afloat或 a double,否则您可以查找任意长的数字库(有许多可用于 C 或 C++)。

回答by Brian Cain

A floatand a doublecan store values in the range you have specified, and beyond.

Afloat和 adouble可以在您指定的范围内以及超出范围存储值。

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

请注意,它不能存储该范围内的精确离散整数,而只能存储通常与数量级相关的近似值。

回答by ouah

Both floatand doublecan store numbers of range at least 1E-37to 1E+37.

双方floatdouble至少能存储的数字范围1E-371E+37

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

如果您需要精确的精度,您可以使用像GMP这样的大 num 库。

回答by Mark B

The doubletype can hold some values up to that range, but it can't represent all integersin 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).

double类型可以容纳该范围内的一些值,但它不能表示该范围内的所有整数(因为如其他答案之一所述,您需要 67 位来表示所有此类整数,而 double 只有 52 位尾数)。

回答by lukai

floator doublecan store the range you desire.You can also use big integer library.Here's an example:

float或者 double可以存储你想要的范围。你也可以使用大整数库。这是一个例子:

// 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. May be it will help you to build your own.

我从这里收集了这个示例库。也许它会帮助你建立自己的。

回答by chinthana

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

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.

float 和 double 数据类型将是答案。但此外我认为 DOUBLE 数据类型是理想的。