PHP 有一个十进制类型,它没有浮点数和双精度数的“不准确性”,因此 2.5 + 2.5 = 5 而不是 4.999999999978325 或类似的东西。
所以我想知道C或C++是否有这样的数据类型实现?
Boost.Multiprecision库有一个名为的基于十进制的浮点模板类cpp_dec_float
,您可以为其指定任何所需的精度。
#include <iostream>
#include <iomanip>
#include <boost/multiprecision/cpp_dec_float.hpp>
int main()
{
namespace mp = boost::multiprecision;
// here I'm using a predefined type that stores 100 digits,
// but you can create custom types very easily with any level
// of precision you want.
typedef mp::cpp_dec_float_100 decimal;
decimal tiny("0.0000000000000000000000000000000000000000000001");
decimal huge("100000000000000000000000000000000000000000000000");
decimal a = tiny;
while (a != huge)
{
std::cout.precision(100);
std::cout << std::fixed << a << '\n';
a *= 10;
}
}
是的:
C++ 有任意精度库。
一个很好的例子是GNU 多精度算术库。
如果您正在寻找支持货币/货币的数据类型,请尝试以下操作: https ://github.com/vpiotr/decimal_for_cpp
(这是仅标题的解决方案)
总会有一些精确度。在任何数字表示的任何计算机上,总会有可以准确表示的数字,而其他数字则不能。
计算机使用 base 2 系统。0.5 (2^-1)、0.125 (2^-3)、0.325 (2^-2 + 2^-3) 等数字将被准确表示(上述情况为 0.1、0.001、0.011)。
在以 3 为底的系统中,这些数字不能准确表示(一半是 0.111111...),但其他数字可以是准确的(例如 2/3 是 0.2)
即使在以 10 为基础的人类系统中,也存在无法准确表示的数字,例如 1/3。
您可以使用有理数表示,以上所有内容都是准确的(1/2、1/3、3/8 等),但总会有一些无理数。您实际上还受到此表示的整数大小的限制。
对于每个不可表示的数字,您可以扩展表示以明确包含它。(例如比较有理数和表示a/b + c/d*sqrt(2)
),但总会有更多的数字仍然无法准确表示。有一个数学证明是这样说的。
所以 - 让我问你这个:你到底需要什么?也许对基于十进制的数字进行精确计算,例如在某些货币计算中?
你问的是反物理。
phyton(以及 C++)所做的就是通过在打印时舍入结果来消除不准确性,方法是减少有效数字的数量:
double x = 2.5;
x += 2.5;
std::cout << x << std::endl;
只是使 x 以 6 位十进制数字精度打印(而 x 本身超过 12),并将四舍五入为 5,消除不精确。
替代方案根本不使用浮点,并实现仅执行整数“缩放”算术的数据类型: 25/10 + 25/10 = 50/10;
但是请注意,这将减少每个整数类型表示的上限。精度(和准确度)的提高将导致更快地到达溢出。
有理算术也是可能的(每个数字由“分子”和“分母”表示),除法没有精度损失,(事实上,除非精确,否则不会这样做)但同样,随着数字的增加值操作的增长(数字越不“理性”,分子和分母越大)溢出的风险就越大。
换句话说,使用有限数量的比特这一事实(无论如何组织)总是会导致您必须在小数字方面付出损失。
我想你说的是 PHP 中的二进制计算器。不,C 运行时或 STL 中没有。但如果你愿意,你可以自己写。
这是使用 Facebook 的 HipHop for PHP 编译的 C++ 版本的 BCMath:http: //fossies.org/dox/facebook-hiphop-php-cf9b612/dir_2abbe3fda61b755422f6c6bae0a5444a.html
作为一种更高级别的语言PHP
只会切断你所谓的“不准确”,但它肯定存在。在 C/C++ 中,您可以通过将结果转换为整数类型来实现类似的效果。