如何表示大数?

发布于 2024-07-05 01:39:32 字数 113 浏览 12 评论 0原文

在 C++ 中处理大数字输入(例如 10^100)的最佳方法是什么?

对于算法,我通常切换到 ruby​​,有时使用字符串。

还有其他好的方法吗?

What is the best way to handle large numeric inputs in C++ (for example 10^100)?

For algorithms I usually switch over to ruby and I sometimes use strings.

Any other good methods?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

一花一树开 2024-07-12 01:39:32

我认为进行此类算术计算的最佳方法是使用字符串。 将输入作为命令行参数提供,然后使用诸如atoi()和itoa()之类的字符串函数来操作整个逻辑! 但是,嘿,这可以用于乘法和除法吗? 我认为通过这种方式,输入的字符串的 strlen 对于编译器的编程并不重要,直到逻辑良好为止。

Well I think the best way to do such arithmetic calculation is by using strings. Give input as command line arguments and then manipulate the whole logic using string functions like atoi() and itoa()! But, hey can this be done for multiplication and Division? I think in this way strlen of strings entered doesn't matter for programming for compiler until the logic is fine.

我们的影子 2024-07-12 01:39:32

考虑 boost:: cpp_int

#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>

int main()
{
   using namespace boost::multiprecision;

   cpp_int u = 1;
   for(unsigned i = 1; i <= 100; ++i)
      u *= i;

   // prints 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 (i.e. 100!)
   std::cout << u << std::endl;

   return 0;
}

Consider boost::cpp_int

#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>

int main()
{
   using namespace boost::multiprecision;

   cpp_int u = 1;
   for(unsigned i = 1; i <= 100; ++i)
      u *= i;

   // prints 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000 (i.e. 100!)
   std::cout << u << std::endl;

   return 0;
}
落在眉间の轻吻 2024-07-12 01:39:32

如果您希望它准确,您需要一个用于处理大数字的库。 Java 拥有 BigInt,无论您想要获取多少位数字,它总是准确的,并提供对它们的数学运算。 所有源代码都包含在内,您可以转移它,但这确实不是 C++ 最擅长的事情——我会使用基于 JVM 的语言并使用 Big 库之一。

我不认为我会为此使用 ruby​​,除非你希望它变慢,并且我假设既然你正在谈论 C++,速度在某种程度上是一个设计考虑因素。

If you want it to be accurate, you need a library made to deal with big numbers. Java has BigInt that will always be accurate no matter how many digits you want to take it to, and provides math operations on them. All the source code is included, you could transfer it, but this really isn't the kind of thing C++ is best at--I'd use a JVM based language and use one of the Big libraries.

I don't think I'd use ruby for this unless you wanted it to be slow, and I'm assuming that since you are talking about C++, speed is somewhat of a design consideration.

℉絮湮 2024-07-12 01:39:32

正如其他人已经指出的那样,C++ 中有各种 bignum/任意精度库,您可能会发现它们很有用。 如果速度不是必需的,我的印象是 Python 和 Lisp 都默认使用 bignum。

As others have already pointed out, there are various bignum/arbitrary precision libraries in C++ that you would likely find useful. If speed isn't necessary, I'm under the impression that Python and Lisp both use bignums by default.

缱倦旧时光 2024-07-12 01:39:32

10^100 这样的大数字需要任意精度的整数。
数字存储为数字序列。 一种非常简单的方法是将它们存储为字符串中的十进制数字序列。 然而,将它们存储为以 232 或 264 为基数的数字序列会更有效,因为每个数字可以完成更多的工作,并且按位运算(如 ) &| 保持快速。

_BitInt(以前称为 _ExtInt

_BitInt 是 clang C++ 编译器扩展(自 clang 14 起;以前称为 _ExtInt) 。
它允许您定义具有任意位数的整数:

// representing 10100 requires at least 333 bits
_BitInt(512) huge = 100..00;

_BitInt 也是 C23 中的标准化功能,尽管目前只有 clang 实现它。

如果您可以将程序的一部分编译为 C,或者完全依赖 clang,那么您无需任何第三方库即可获得任意精度。

第三方库

标准库中还没有任何 big_int 类,但您可以使用第三方库:

格式功能
Boost.Multi precisionC++ 库任意和无限精度整数,
任意精度浮点数
< a href="https://gmplib.org/" rel="nofollow noreferrer">GMP(GNU 多精度
算术库)
C 库
(C++ 兼容)
任意和无限精度整数,
任意精度浮点
MPIR(多精度整数
和有理数)
的分叉GMP与 GMP 类似,但使用 Visual Studio 进行编译
并具有一些额外功能
BigDigits< /a>C 库
(C++ 兼容)
任意和无限精度整数
ttmath (Bignum C++库)C++ 库任意精度整数和浮点数
faheel/BigIntC++ 头文件 无限精度整数
< a href="https://github.com/rgroshanrg/bigint" rel="nofollow noreferrer">rgroshanrg/bigintC++ 单头无限精度整数
sercantutar/infintC++ 单头无限精度整数

有关更多库,请参阅 维基百科:任意精度算术软件列表


注:“任意精度”意味着一个数字可以有任意固定数量的位数,而“无限精度”意味着需要时可以增加位数。

Large numbers like 10^100 require arbitrary precision integers.
Numbers are stored as a sequence of digits. A very naive way is to store them as a sequence of decimal digits in a string. However, it is more efficient to store them as a sequence of digits base 232 or 264 since more work can be done per digit, and bitwise operations like & and | remain fast.

_BitInt (formerly _ExtInt)

_BitInt is a clang C++ compiler extension (since clang 14; formerly known as _ExtInt).
It lets you define integers with an arbitrary amount of bits:

// representing 10100 requires at least 333 bits
_BitInt(512) huge = 100..00;

_BitInt is also a standardized feature in C23, although only clang implements it at this time.

If you are okay with compiling a portion of your program as C, or with relying exclusively on clang, then you can get arbitrary precision without any third-party libraries.

Third-Party Libraries

There isn't any big_int class in the standard library yet, but you can use third-party libraries:

LibraryFormatFeatures
Boost.MultiprecisionC++ libraryArbitrary and infinite precision integers,
arbitrary precision floating-point
GMP (GNU Multiple Precision
Arithmetic Library)
C library
(C++-compatible)
Arbitrary and infinite precision integers,
arbitrary precision floating-point
MPIR (Multiple Precision Integers
and Rationals)
Fork of GMPSimilar to GMP, but compiles with Visual Studio
and has some extra features
BigDigitsC library
(C++-compatible)
Arbitrary and infinite precision integers
ttmath (Bignum C++ library)C++ libraryArbitrary precision integers and floating-point
faheel/BigIntC++ header-onlyInfinite precision integers
rgroshanrg/bigintC++ single-headerInfinite precision integers
sercantutar/infintC++ single-headerInfinite precision integers

For more libraries, see Wikipedia: List of arbitrary-precision arithmetic software


Note: "arbitrary precision" means that a number can have any fixed amount of bits, whereas "infinite precision" means that the amount of bits can increase when needed.

口干舌燥 2024-07-12 01:39:32

您是否正在寻找如何对收到的大量输入执行操作? 有一个 大整数 C++ 库(类似于 Java),允许您执行算术运算运营...

Are you looking for how to perform operations on the large inputs you receive? There is a big integer C++ library (similar to Java) that allows you to perform arithmetic operations...

泪痕残 2024-07-12 01:39:32

假设您正在谈论输入数字,双精度将使您达到 1.7976931348623157 x 10^308

assuming you are talking about inputting numbers, double precision would get you up to 1.7976931348623157 x 10^308

青巷忧颜 2024-07-12 01:39:32

您可能想看看 gmplib,这是一个用于 C 和 C++ 的任意精度数字处理库

You might want to have a look to gmplib, an arbitrary precision number handling library for C and C++

小姐丶请自重 2024-07-12 01:39:32

如果您希望为此目的编写自己的代码,请尝试使用字符串来存储大数字...然后您可以在它们上创建像 + - / * 这样的基本操作...例如 -

#include <iostream>

using namespace std;

string add (string &s1, string &s2){
    int carry=0,sum,i;

    string  min=s1,
    max=s2,
    result = "";

    if (s1.length()>s2.length()){
        max = s1;
        min = s2;
    } else {
        max = s2;
        min = s1;
    }

    for (i = min.length()-1; i>=0; i--){
        sum = min[i] + max[i + max.length() - min.length()] + carry - 2*'0';

        carry = sum/10;
        sum %=10;

        result = (char)(sum + '0') + result;
    }

    i = max.length() - min.length()-1;

    while (i>=0){
        sum = max[i] + carry - '0';
        carry = sum/10;
        sum%=10;

        result = (char)(sum + '0') + result;
        i--;
    }

    if (carry!=0){
        result = (char)(carry + '0') + result;
    }       

    return result;
}

int main (){
    string a,b;

    cin >> a >> b;

    cout << add (a,b)<<endl;

    return 0;
}

If you wish to make your own code for the purpose try using strings to store big numbers... you can then create basic ops like + - / * on them... for example -

#include <iostream>

using namespace std;

string add (string &s1, string &s2){
    int carry=0,sum,i;

    string  min=s1,
    max=s2,
    result = "";

    if (s1.length()>s2.length()){
        max = s1;
        min = s2;
    } else {
        max = s2;
        min = s1;
    }

    for (i = min.length()-1; i>=0; i--){
        sum = min[i] + max[i + max.length() - min.length()] + carry - 2*'0';

        carry = sum/10;
        sum %=10;

        result = (char)(sum + '0') + result;
    }

    i = max.length() - min.length()-1;

    while (i>=0){
        sum = max[i] + carry - '0';
        carry = sum/10;
        sum%=10;

        result = (char)(sum + '0') + result;
        i--;
    }

    if (carry!=0){
        result = (char)(carry + '0') + result;
    }       

    return result;
}

int main (){
    string a,b;

    cin >> a >> b;

    cout << add (a,b)<<endl;

    return 0;
}
滥情空心 2024-07-12 01:39:32

听起来您正在寻找一种输入任意精度数字的方法。
这里有两个你可以使用的库: GMPMAPM

It sounds like you're looking for a way to enter Arbitrary Precision numbers.
here are two libraries you could use: GMP and MAPM

〗斷ホ乔殘χμё〖 2024-07-12 01:39:32

查看C++ 中的大整数案例研究.pdf< /strong> 作者:欧文·阿斯特拉坎。 我发现这个文件非常有用,有详细的介绍和代码实现。 它不使用任何第三方库。 我已经用它来处理巨大的数字(只要你有足够的内存来存储vector),没有任何问题。


想法
它通过将 big int 存储在 vector 中来实现任意精度整数类。

vector<char> myDigits; // stores all digits of number

那么所有与big int相关的操作,包括<<、>>、+、-、*、==、<、!=、>等,都可以基于此 char 数组 上的操作完成。


代码品味
这是头文件,你可以在pdf文件中找到它的cpp和代码。

#include <iostream>
#include <string> // for strings
#include <vector> // for sequence of digits
using namespace std;

class BigInt
{
public:
    BigInt(); // default constructor, value = 0
    BigInt(int); // assign an integer value
    BigInt(const string &); // assign a string
    // may need these in alternative implementation
    // BigInt(const BigInt &); // copy constructor
    // ~BigInt(); // destructor
    // const BigInt & operator = (const BigInt &);
    // assignment operator
    // operators: arithmetic, relational
    const BigInt & operator += (const BigInt &);
    const BigInt & operator -= (const BigInt &);
    const BigInt & operator *= (const BigInt &);
    const BigInt & operator *= (int num);
    string ToString() const; // convert to string
    int ToInt() const; // convert to int
    double ToDouble() const; // convert to double
    // facilitate operators ==, <, << without friends
    bool Equal(const BigInt & rhs) const;
    bool LessThan(const BigInt & rhs) const;
    void Print(ostream & os) const;
private:
    // other helper functions
    bool IsNegative() const; // return true iff number is negative
    bool IsPositive() const; // return true iff number is positive
    int NumDigits() const; // return # digits in number
    int GetDigit(int k) const;
    void AddSigDigit(int value);
    void ChangeDigit(int k, int value);
    void Normalize();
    // private state/instance variables
    enum Sign{positive,negative};
    Sign mySign; // is number positive or negative
    vector<char> myDigits; // stores all digits of number
    int myNumDigits; // stores # of digits of number
};

// free functions
ostream & operator <<(ostream &, const BigInt &);
istream & operator >>(istream &, BigInt &);
BigInt operator +(const BigInt & lhs, const BigInt & rhs);
BigInt operator -(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, int num);
BigInt operator *(int num, const BigInt & rhs);
bool operator == (const BigInt & lhs, const BigInt & rhs);
bool operator < (const BigInt & lhs, const BigInt & rhs);
bool operator != (const BigInt & lhs, const BigInt & rhs);
bool operator > (const BigInt & lhs, const BigInt & rhs);
bool operator >= (const BigInt & lhs, const BigInt & rhs);
bool operator <= (const BigInt & lhs, const BigInt & rhs);

Check out The Large Integer Case Study in C++.pdf by Owen Astrachan. I found this file extremely useful with detail introduction and code implementation. It doesn't use any 3rd-party library. I have used this to handle huge numbers (as long as you have enough memory to store vector<char>) with no problems.


Idea:
It implements an arbitrary precision integer class by storing big int in a vector<char>.

vector<char> myDigits; // stores all digits of number

Then all operations related to the big int, including <<, >>, +, -, *, ==, <, !=, >, etc., can be done based on operations on this char array.


Taste of the code:
Here is the header file, you can find its cpp with codes in the pdf file.

#include <iostream>
#include <string> // for strings
#include <vector> // for sequence of digits
using namespace std;

class BigInt
{
public:
    BigInt(); // default constructor, value = 0
    BigInt(int); // assign an integer value
    BigInt(const string &); // assign a string
    // may need these in alternative implementation
    // BigInt(const BigInt &); // copy constructor
    // ~BigInt(); // destructor
    // const BigInt & operator = (const BigInt &);
    // assignment operator
    // operators: arithmetic, relational
    const BigInt & operator += (const BigInt &);
    const BigInt & operator -= (const BigInt &);
    const BigInt & operator *= (const BigInt &);
    const BigInt & operator *= (int num);
    string ToString() const; // convert to string
    int ToInt() const; // convert to int
    double ToDouble() const; // convert to double
    // facilitate operators ==, <, << without friends
    bool Equal(const BigInt & rhs) const;
    bool LessThan(const BigInt & rhs) const;
    void Print(ostream & os) const;
private:
    // other helper functions
    bool IsNegative() const; // return true iff number is negative
    bool IsPositive() const; // return true iff number is positive
    int NumDigits() const; // return # digits in number
    int GetDigit(int k) const;
    void AddSigDigit(int value);
    void ChangeDigit(int k, int value);
    void Normalize();
    // private state/instance variables
    enum Sign{positive,negative};
    Sign mySign; // is number positive or negative
    vector<char> myDigits; // stores all digits of number
    int myNumDigits; // stores # of digits of number
};

// free functions
ostream & operator <<(ostream &, const BigInt &);
istream & operator >>(istream &, BigInt &);
BigInt operator +(const BigInt & lhs, const BigInt & rhs);
BigInt operator -(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, const BigInt & rhs);
BigInt operator *(const BigInt & lhs, int num);
BigInt operator *(int num, const BigInt & rhs);
bool operator == (const BigInt & lhs, const BigInt & rhs);
bool operator < (const BigInt & lhs, const BigInt & rhs);
bool operator != (const BigInt & lhs, const BigInt & rhs);
bool operator > (const BigInt & lhs, const BigInt & rhs);
bool operator >= (const BigInt & lhs, const BigInt & rhs);
bool operator <= (const BigInt & lhs, const BigInt & rhs);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文