我们可以将字符串用于高精度浮点数吗?
Could we use strings for high precision floating-point numbers?
我目前正在编写一个需要高精度浮点数的软件。有时我需要比 double
更精确的精度。我知道为什么经典的浮点数只能达到有限的精度。
我在思考这个问题,萌生了用string
来表示数字并用它们进行计算的想法。
string number_one = "12.3459233547343432";
string number_two = "738.67632487523747384";
string sum = sum_strings(number_one, number_two);
cout << sum << endl; // 751.0222482299717...
然后函数 sum_strings
将执行加法,就像我们在小学时都学过的那样(只是用浮点数):
减法的工作方式相同。乘法和除法会更复杂,但也可以。
我认为理论上您可以达到所需的精度(有足够的 RAM 来存储字符串)。
我的问题是:
- 这种技术会慢很多吗(约 10 个小数位)?
- 它是否已被使用并且是否有实现它的库?
这会慢很多,因为您将对一位数据使用完整的字符,并且您执行的操作将完全无法使用硬件实现的算术运算。更好的方法是设计一种任意长度的二进制格式。参见 https://gmplib.org。还有很多其他选择。
您的方向是正确的,但是 std::string
不是正确的数据结构。相反,使用 std::vector<unsigned char>
,向量的每个元素都包含 0
到 std::numeric_limits<unsigned char>::max()
范围内的值。这个上限通常是 255。加法和减法的规则就像你小时候学的一样,除了你有 256 个手指而不是 10 个。这听起来很轻率,但想法是你有一堆数字一个数字的 base-256 表示,加法和减法的规则是一样的,除了当结果大于 255 时你进位,而不是当它大于 9 时。这比听起来容易;只需使用更大的无符号类型进行算术运算;结果%256为当前位的值,结果/256为进位量
一旦你想清楚了,你也可以考虑使用 std::vector<unsigned long long>
而不是 std::vector<unsigned char>
,这意味着在 base-2^64 中进行算术运算。
我目前正在编写一个需要高精度浮点数的软件。有时我需要比 double
更精确的精度。我知道为什么经典的浮点数只能达到有限的精度。
我在思考这个问题,萌生了用string
来表示数字并用它们进行计算的想法。
string number_one = "12.3459233547343432";
string number_two = "738.67632487523747384";
string sum = sum_strings(number_one, number_two);
cout << sum << endl; // 751.0222482299717...
然后函数 sum_strings
将执行加法,就像我们在小学时都学过的那样(只是用浮点数):
减法的工作方式相同。乘法和除法会更复杂,但也可以。
我认为理论上您可以达到所需的精度(有足够的 RAM 来存储字符串)。
我的问题是:
- 这种技术会慢很多吗(约 10 个小数位)?
- 它是否已被使用并且是否有实现它的库?
这会慢很多,因为您将对一位数据使用完整的字符,并且您执行的操作将完全无法使用硬件实现的算术运算。更好的方法是设计一种任意长度的二进制格式。参见 https://gmplib.org。还有很多其他选择。
您的方向是正确的,但是 std::string
不是正确的数据结构。相反,使用 std::vector<unsigned char>
,向量的每个元素都包含 0
到 std::numeric_limits<unsigned char>::max()
范围内的值。这个上限通常是 255。加法和减法的规则就像你小时候学的一样,除了你有 256 个手指而不是 10 个。这听起来很轻率,但想法是你有一堆数字一个数字的 base-256 表示,加法和减法的规则是一样的,除了当结果大于 255 时你进位,而不是当它大于 9 时。这比听起来容易;只需使用更大的无符号类型进行算术运算;结果%256为当前位的值,结果/256为进位量
一旦你想清楚了,你也可以考虑使用 std::vector<unsigned long long>
而不是 std::vector<unsigned char>
,这意味着在 base-2^64 中进行算术运算。