有没有 C++相当于Java的BigDecimal?

发布于 2024-10-14 03:19:26 字数 351 浏览 2 评论 0原文

我正在寻找一个可以进行十进制浮点运算的 C++ 类。浏览 http://speleotrove.com/decimal/ 可以找到人们编写的各种类的链接并且没有维护。通过深入研究 decNumber++ 的内容,我发现了一些电子邮件,表明 GCC 最终将支持此功能。 (正式名称为 ISO/IEC TR 24733)

我正在寻找可以用作 float 或 double 的直接替代品,其他人在自己的项目中使用的东西。希望开源。

谢谢!

编辑:我应该指出,我试图用它来代表价格。所以我需要精确的小数,而不是巨大的小数。

I'm looking for a C++ class that can do decimal floating point arithmetic. Looking through http://speleotrove.com/decimal/ there are links to all sorts of classes that people have written and not maintained. Digging through the decNumber++ stuff led me to some emails showing that GCC will eventually support this functionality. (Formally known as ISO/IEC TR 24733)

I'm looking for something I can use as a drop-in replacement for float or double, something that other people are using in their own projects. Hopefully open source.

Thanks!

EDIT: I should point out that I'm trying to use this to represent prices. So I need EXACT decimals, not HUGE decimals.

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

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

发布评论

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

评论(9

趴在窗边数星星i 2024-10-21 03:19:26

存在一个名为 GMP(GNU 多精度库) 的巨大库,它支持此功能,并且还具有 C++ 绑定,不过说实话C++ 接口有点不稳定且过时。

文档中的一个示例,以下创建了一个名为 f 的浮点数,其精度至少为 500 位:

mpf_class f(1.5, 500);

There exists a huge library called GMP (GNU multiple precision library) which supports this and also has C++ bindings, though to be honest the C++ interface is a bit wonky and outdated.

An example from the documentation, the following creates a float called f with at least 500 bits of precision:

mpf_class f(1.5, 500);
£冰雨忧蓝° 2024-10-21 03:19:26

随你挑选。那里有很多这样的人。例如,您可以查阅维基百科上的列表

Take your pick. There are a bunch of them out there. For instance, you can consult the list on Wikipedia.

感情洁癖 2024-10-21 03:19:26

这个问题有点老了,但对于其他有相同需求的人来说:Boost.multi precision 可能就是您正在寻找的。

http://www .boost.org/doc/libs/1_57_0/libs/multi precision/doc/html/boost_multi precision/tut/floats/cpp_dec_float.html

这是一个任意精度库,可以处理基于 10 的小数。

The question is a bit old, but for other people that have the same need : Boost.multiprecision is probably what you're looking for.

http://www.boost.org/doc/libs/1_57_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html

It's an arbitrary precision library that can handle 10-based decimals.

这样的小城市 2024-10-21 03:19:26

如果您需要使用巨大的十进制值进行运算,我建议您使用 http://gmplib.org/ 库。我在 C 和 C++ 中经常使用它。

If you need to do operations with HUGE decimal values I would suggest you to use http://gmplib.org/ library. I've used it a lot with C and C++.

猫卆 2024-10-21 03:19:26

使用 GMP 并将所有内容存储为美分。如果您知道您不会传递 2^32 美分(42949673 万美元),请使用 32 位无符号 int(或使用 64 位无符号 int)并保持简单。

Use GMP and store everything as cents. If you know that you won't pass 2^32 cents (42.949673 million dollars) use a 32 bit unsigned int (or use a 64 bit unsigned int) and keep it simple.

不再让梦枯萎 2024-10-21 03:19:26

我可能来得太晚了,但是 128 位小数可以吗?
这些已经被 C++ 接受,并且至少从 gcc-4.5 开始就有了它们(我们现在开始 4.9:

#include <iostream>
#include <decimal/decimal>

using namespace std;

int main()
{
  {
    std::decimal::decimal32 dn(.3), dn2(.099), dn3(1000), dn4(201);
    dn-=dn2;
    dn*=dn3;
    cout << "decimal32 = "  << (dn==dn4) << " : " << decimal32_to_double(dn) << endl;
  }

  {
    std::decimal::decimal64 dn(.3), dn2(.099), dn3(1000), dn4(201);
    dn-=dn2;
    dn*=dn3;
    cout << "decimal64 = "  << (dn==dn4) << " : " << decimal64_to_double(dn) << endl;
  }

  {
    std::decimal::decimal128 dn(.3), dn2(.099), dn3(1000), dn4(201);
    dn-=dn2;
    dn*=dn3;
    cout << "decimal128 = " << (dn==dn4) << " : " << decimal128_to_double(dn) << endl;
  }

  return 0;
}

注意,decimal32 的大小等于 float,decimal64 的大小等于大多数 double。因此,decimal128 相当大。从 < a href="http://en.wikipedia.org/wiki/Decimal128_floating-point_format" rel="nofollow">Wikipedia:Decimal128 支持 34 位十进制有效位数,指数范围为 −6143 到 +6144,即±0.000000000000000000000000000000000×10−6143到±9.99999999999999999999999999999999×106144。(相当于±00000000000000000000000000 00000000×10−6176 到 ±999999999999999999999999999999999×106111。)

mpfr 库是任意精度二进制浮点 - 不是任意精度十进制。

I may be too late for this but would 128bit decimals work?
These have been accepted into C++ and at least gcc has them since gcc-4.5 (we're starting 4.9 now:

#include <iostream>
#include <decimal/decimal>

using namespace std;

int main()
{
  {
    std::decimal::decimal32 dn(.3), dn2(.099), dn3(1000), dn4(201);
    dn-=dn2;
    dn*=dn3;
    cout << "decimal32 = "  << (dn==dn4) << " : " << decimal32_to_double(dn) << endl;
  }

  {
    std::decimal::decimal64 dn(.3), dn2(.099), dn3(1000), dn4(201);
    dn-=dn2;
    dn*=dn3;
    cout << "decimal64 = "  << (dn==dn4) << " : " << decimal64_to_double(dn) << endl;
  }

  {
    std::decimal::decimal128 dn(.3), dn2(.099), dn3(1000), dn4(201);
    dn-=dn2;
    dn*=dn3;
    cout << "decimal128 = " << (dn==dn4) << " : " << decimal128_to_double(dn) << endl;
  }

  return 0;
}

Note there is decimal32 equal in size to float, decimal64 equal in size to most double. So decimal128 is pretty big. From Wikipedia: Decimal128 supports 34 decimal digits of significand and an exponent range of −6143 to +6144, i.e. ±0.000000000000000000000000000000000×10−6143 to ±9.999999999999999999999999999999999×106144. (Equivalently, ±0000000000000000000000000000000000×10−6176 to ±9999999999999999999999999999999999×106111.)

The mpfr library is arbitrary precision binary floating point - not arbitrary precision decimal. There is a difference.

追星践月 2024-10-21 03:19:26

这是 BCMath PHP 到 C++ 的实现。有两种版本,一种用于 Qt,另一种仅使用 STL。

来源:https://github.com/DesarrollosCuado/BCMath-for-Cpp

BCMath::bcscale(4); //Num Decimals
BCMath test("-5978");

test^=30; //Pow, only integers. Not work decimals.
std::cout<<"Result BigDecimal 1: "<<test.toString().c_str()<<std::endl;

test-=1.23; //sub
std::cout<<"Result BigDecimal 2: "<<test.toString().c_str()<<std::endl;

test*=1.23; //mul
std::cout<<"Result BigDecimal 3: "<<test.toString().c_str()<<std::endl;

test*=-1.23; //mul
std::cout<<"Result BigDecimal 4: "<<test.toString().c_str()<<std::endl;

BCMath::bcscale(70); //Num Decimals

BCMath randNum("-5943534512345234545.8998928392839247844353457");
BCMath pi("3.1415926535897932384626433832795028841971693993751058209749445923078164062862");

BCMath result1 = randNum + pi;
BCMath result2 = randNum - pi;
BCMath result3 = randNum * pi;
BCMath result4 = randNum / pi;

std::cout<<"Result Super Precision 1: "<<result1.toString().c_str()<<std::endl;
std::cout<<"Result Super Precision 2: "<<result2.toString().c_str()<<std::endl;
std::cout<<"Result Super Precision 3: "<<result3.toString().c_str()<<std::endl;
std::cout<<"Result Super Precision 4: "<<result4.toString().c_str()<<std::endl;

//Other example
BCMath::bcscale(4); //Num Decimals
std::cout<<"Other 1: "<<BCMath::bcmul("1000000.0134", "8.0234").c_str()<<std::endl;
std::cout<<"Other 2: "<<BCMath::bcadd("1000000.0134", "8.0234").c_str()<<std::endl;

std::cout<<"Compare 1:  "<<BCMath::bccomp("1", "2")<<std::endl;
std::cout<<"Compare 2:  "<<BCMath::bccomp("1.00001", "1", 3)<<std::endl;
std::cout<<"Compare 3:  "<<BCMath::bccomp("1.00001", "1", 5)<<std::endl;
std::cout<<"Compare 4:  "<<(BCMath("1")< BCMath("2"))<<std::endl;
std::cout<<"Compare 5:  "<<(BCMath("1")<=BCMath("2"))<<std::endl;
std::cout<<"Compare 6:  "<<(BCMath("1")> BCMath("2"))<<std::endl;
std::cout<<"Compare 7:  "<<(BCMath("1")>=BCMath("2"))<<std::endl;
std::cout<<"Compare 8:  "<<(BCMath("2")< BCMath("2"))<<std::endl;
std::cout<<"Compare 9:  "<<(BCMath("2")<=BCMath("2"))<<std::endl;
std::cout<<"Compare 10: "<<(BCMath("2")> BCMath("2"))<<std::endl;
std::cout<<"Compare 11: "<<(BCMath("2")>=BCMath("2"))<<std::endl;

std::cout<<"Round 1: "<<BCMath::bcround("123.01254").c_str()<<std::endl;
std::cout<<"Round 2: "<<BCMath::bcround("-123.01254", 3).c_str()<<std::endl;
std::cout<<"Round 3: "<<BCMath::bcround("123.01254", 2).c_str()<<std::endl;
pi.round(3);
std::cout<<"Round 4: "<<pi.toString().c_str()<<std::endl;

BCMath part1("-.123");
BCMath part2(".123");
BCMath part3("123");
std::cout<<"Int part 1: "<<part1.getIntPart().c_str()<<std::endl;
std::cout<<"Dec part 1: "<<part1.getDecPart().c_str()<<std::endl;
std::cout<<"Int part 2: "<<part2.getIntPart().c_str()<<std::endl;
std::cout<<"Dec part 2: "<<part2.getDecPart().c_str()<<std::endl;
std::cout<<"Int part 3: "<<part3.getIntPart().c_str()<<std::endl;
std::cout<<"Dec part 3: "<<part3.getDecPart().c_str()<<std::endl;

结果:

Result BigDecimal 1:  198005530669253749533290222782634796336450786581284861381777714804795900171726938603997395193921984842256586113024
Result BigDecimal 2:  198005530669253749533290222782634796336450786581284861381777714804795900171726938603997395193921984842256586113022.7700
Result BigDecimal 3:  243546802723182111925946974022640799493834467494980379499586589209898957211224134482916796088524041355975600919018.0071
Result BigDecimal 4:  -299562567349513997668914778047848183377416395018825866784491504728175717369805685413987659188884570867849989130392.1487

Result Super Precision 1:  -5943534512345234542.7583001856941315459727023167204971158028306006248941790250554076921835
Result Super Precision 2:  -5943534512345234549.0414854928737180228979890832795028841971693993751058209749445923078164
Result Super Precision 3:  -18672164360341183116.9114783895073349180904753962992796943871920962352436079118338887287186
Result Super Precision 4:  -1891885794154043400.2804849527556211973567525043250278948318788149660700494315139982452600

Other 1:  8023400.1075
Other 2:  1000008.0368

Compare 1:   -1
Compare 2:   0
Compare 3:   1
Compare 4:   true
Compare 5:   true
Compare 6:   false
Compare 7:   false
Compare 8:   false
Compare 9:   true
Compare 10:  false
Compare 11:  true

Round 1:  123.0125
Round 2:  -123.013
Round 3:  123.01
Round 4:  3.142

Int part 1:  -0
Dec part 1:  123
Int part 2:  0
Dec part 2:  123
Int part 3:  123
Dec part 3:  0

Here is an implementation of BCMath PHP to C++. There are two versions, one for Qt and the other for use only STL.

Source: https://github.com/DesarrollosCuado/BCMath-for-Cpp

BCMath::bcscale(4); //Num Decimals
BCMath test("-5978");

test^=30; //Pow, only integers. Not work decimals.
std::cout<<"Result BigDecimal 1: "<<test.toString().c_str()<<std::endl;

test-=1.23; //sub
std::cout<<"Result BigDecimal 2: "<<test.toString().c_str()<<std::endl;

test*=1.23; //mul
std::cout<<"Result BigDecimal 3: "<<test.toString().c_str()<<std::endl;

test*=-1.23; //mul
std::cout<<"Result BigDecimal 4: "<<test.toString().c_str()<<std::endl;

BCMath::bcscale(70); //Num Decimals

BCMath randNum("-5943534512345234545.8998928392839247844353457");
BCMath pi("3.1415926535897932384626433832795028841971693993751058209749445923078164062862");

BCMath result1 = randNum + pi;
BCMath result2 = randNum - pi;
BCMath result3 = randNum * pi;
BCMath result4 = randNum / pi;

std::cout<<"Result Super Precision 1: "<<result1.toString().c_str()<<std::endl;
std::cout<<"Result Super Precision 2: "<<result2.toString().c_str()<<std::endl;
std::cout<<"Result Super Precision 3: "<<result3.toString().c_str()<<std::endl;
std::cout<<"Result Super Precision 4: "<<result4.toString().c_str()<<std::endl;

//Other example
BCMath::bcscale(4); //Num Decimals
std::cout<<"Other 1: "<<BCMath::bcmul("1000000.0134", "8.0234").c_str()<<std::endl;
std::cout<<"Other 2: "<<BCMath::bcadd("1000000.0134", "8.0234").c_str()<<std::endl;

std::cout<<"Compare 1:  "<<BCMath::bccomp("1", "2")<<std::endl;
std::cout<<"Compare 2:  "<<BCMath::bccomp("1.00001", "1", 3)<<std::endl;
std::cout<<"Compare 3:  "<<BCMath::bccomp("1.00001", "1", 5)<<std::endl;
std::cout<<"Compare 4:  "<<(BCMath("1")< BCMath("2"))<<std::endl;
std::cout<<"Compare 5:  "<<(BCMath("1")<=BCMath("2"))<<std::endl;
std::cout<<"Compare 6:  "<<(BCMath("1")> BCMath("2"))<<std::endl;
std::cout<<"Compare 7:  "<<(BCMath("1")>=BCMath("2"))<<std::endl;
std::cout<<"Compare 8:  "<<(BCMath("2")< BCMath("2"))<<std::endl;
std::cout<<"Compare 9:  "<<(BCMath("2")<=BCMath("2"))<<std::endl;
std::cout<<"Compare 10: "<<(BCMath("2")> BCMath("2"))<<std::endl;
std::cout<<"Compare 11: "<<(BCMath("2")>=BCMath("2"))<<std::endl;

std::cout<<"Round 1: "<<BCMath::bcround("123.01254").c_str()<<std::endl;
std::cout<<"Round 2: "<<BCMath::bcround("-123.01254", 3).c_str()<<std::endl;
std::cout<<"Round 3: "<<BCMath::bcround("123.01254", 2).c_str()<<std::endl;
pi.round(3);
std::cout<<"Round 4: "<<pi.toString().c_str()<<std::endl;

BCMath part1("-.123");
BCMath part2(".123");
BCMath part3("123");
std::cout<<"Int part 1: "<<part1.getIntPart().c_str()<<std::endl;
std::cout<<"Dec part 1: "<<part1.getDecPart().c_str()<<std::endl;
std::cout<<"Int part 2: "<<part2.getIntPart().c_str()<<std::endl;
std::cout<<"Dec part 2: "<<part2.getDecPart().c_str()<<std::endl;
std::cout<<"Int part 3: "<<part3.getIntPart().c_str()<<std::endl;
std::cout<<"Dec part 3: "<<part3.getDecPart().c_str()<<std::endl;

Result:

Result BigDecimal 1:  198005530669253749533290222782634796336450786581284861381777714804795900171726938603997395193921984842256586113024
Result BigDecimal 2:  198005530669253749533290222782634796336450786581284861381777714804795900171726938603997395193921984842256586113022.7700
Result BigDecimal 3:  243546802723182111925946974022640799493834467494980379499586589209898957211224134482916796088524041355975600919018.0071
Result BigDecimal 4:  -299562567349513997668914778047848183377416395018825866784491504728175717369805685413987659188884570867849989130392.1487

Result Super Precision 1:  -5943534512345234542.7583001856941315459727023167204971158028306006248941790250554076921835
Result Super Precision 2:  -5943534512345234549.0414854928737180228979890832795028841971693993751058209749445923078164
Result Super Precision 3:  -18672164360341183116.9114783895073349180904753962992796943871920962352436079118338887287186
Result Super Precision 4:  -1891885794154043400.2804849527556211973567525043250278948318788149660700494315139982452600

Other 1:  8023400.1075
Other 2:  1000008.0368

Compare 1:   -1
Compare 2:   0
Compare 3:   1
Compare 4:   true
Compare 5:   true
Compare 6:   false
Compare 7:   false
Compare 8:   false
Compare 9:   true
Compare 10:  false
Compare 11:  true

Round 1:  123.0125
Round 2:  -123.013
Round 3:  123.01
Round 4:  3.142

Int part 1:  -0
Dec part 1:  123
Int part 2:  0
Dec part 2:  123
Int part 3:  123
Dec part 3:  0
顾忌 2024-10-21 03:19:26

您可以使用 BigDecimal 的下一个 cpp 实现:

https://github.com/Sam-bit/ BigDecimal-CPP

谨致问候。

you can use the next cpp implementation of BigDecimal:

https://github.com/Sam-bit/BigDecimal-CPP

Best Regards.

柒夜笙歌凉 2024-10-21 03:19:26

也许“MAPM,C 语言的便携式任意精度数学库”就是您正在寻找的。它还包括 C++ 包装器:

http://www.tc.umn.edu/ ~ringx004/mapm-main.html

Probably "MAPM, A Portable Arbitrary Precision Math Library in C" is what you are looking for. It also includes C++ Wrappers:

http://www.tc.umn.edu/~ringx004/mapm-main.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文