简体   繁体   English

我们可以将字符串用于高精度浮点数吗?

[英]Could we use strings for high precision floating-point numbers?

I am currently programming a software which needs high precision floating-point numbers. 我目前正在编程需要高精度浮点数的软件。 Sometimes I need more precision than a double can give me. 有时我需要的精度比double精度所能提供的精度高。 I know why classic floating-point numbers can only achieve a limited amount of precision. 我知道为什么经典浮点数只能达到有限的精度。

I was thinking about this problem and had the idea to use string to represent numbers and do calculation with them. 我在考虑这个问题,并且想到了使用string来表示数字并对其进行计算。

string number_one = "12.3459233547343432";
string number_two = "738.67632487523747384";

string sum = sum_strings(number_one, number_two);

cout << sum << endl; // 751.0222482299717...

The function sum_strings would then perform the addition like we have all learned it in primary school (just with floating-point): 函数sum_strings然后将执行加法sum_strings ,就像我们在小学时就已经学过一样(只是浮点运算):

在此处输入图片说明

Substraction would work the same way. 减法将以相同的方式工作。 Multiplication and division would be more complicated but it would also work. 乘法和除法会更复杂,但也可以。

I think theoretically you could achieve as much precision as you need (with enough RAM to store the strings). 我认为从理论上讲,您可以达到所需的精度(具有足够的RAM来存储字符串)。

My questions are: 我的问题是:

  1. Would this technique be much slower (for ~10 fractional digits)? 这种技术会慢很多吗(约10个小数位)?
  2. Is it used already and are there libraries implementing it? 它已经被使用了吗?

This would be quite a bit slower, since you'd be using a full char for a single digit of data, and operations you performed would be totally unable to use hardware-implemented arithmetic operations. 这会慢很多,因为您将对单个数据使用完整的char,并且您执行的操作将完全无法使用硬件实现的算术运算。 A much better way would be to design an arbitrary-length binary format instead. 更好的方法是改为设计任意长度的二进制格式。 See https://gmplib.org . 参见https://gmplib.org There are many other options as well. 还有许多其他选择。

You're on the right track, but std::string is not the right data structure. 您处在正确的轨道上,但是std::string不是正确的数据结构。 Instead, use std::vector<unsigned char> , with each element of the vector holding a value in the range 0 to std::numeric_limits<unsigned char>::max() . 而是使用std::vector<unsigned char> ,向量的每个元素都保存一个介于0std::numeric_limits<unsigned char>::max()范围内的值。 That upper limit is typically 255. The rules for addition and subtraction are just like the ones you learned as a kid, except that you have 256 fingers instead of 10. That sounds flippant, but the idea is that you have a bunch of digits for a base-256 representation of a number, and the rules for adding and subtracting work the same, except that you carry when the result is greater than 255, not when it's greater than 9. That's easier than it sounds; 上限通常为255。加法和减法的规则与您小时候所学的规则相同,不同之处在于您的手指数为256,而不是10。这听起来有些flip昧,但想法是,您有很多数字一个以256为底的数字表示形式,以及加减法则相同。不同之处在于,当结果大于255而不是大于9时,您必须携带该值。 just do the arithmetic with a larger unsigned type; 只是使用更大的无符号类型进行算术运算; the result % 256 is the value in the current digit, and the result / 256 is the amount to carry. 结果%256是当前数字的值,结果/ 256是要携带的数量。

Once you've wrapped your thoughts around that, you could also consider using std::vector<unsigned long long> instead of std::vector<unsigned char> , which would mean doing arithmetic in base-2^64. 一旦您解决了这个问题,您还可以考虑使用std::vector<unsigned long long>代替std::vector<unsigned char> ,这意味着在base-2 ^ 64中进行算术运算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM