可靠地将字符串转换为双精度和反精度

Reliable convert strings to doubles and back

本文关键字:双精度 精度 转换 字符串      更新时间:2023-10-16

我一直在寻找函数,以便在c++中将字符串可靠地转换为双精度,然后再转换回字符串,从而使输出字符串与输入字符串完全相同。但即使经过数小时的搜索和试用,我也找不到可靠的功能。

为了检查功能是否可靠,我进行了以下测试:

#include <iostream>
#include <string>
using namespace std;
string double2string(double value){
    //...
}
double string2double(string value){
    //...
}

int main(){
    string strings[] = {
        "111111111111110000",
        "11111111111111000",
        "1111111111111100",
        "111111111111110",
        "11111111111111",
        "1111111111111.1",
        "111111111111.11",
        "11111111111.111",
        "1111111111.1111",
        "111111111.11111",
        "11111111.111111",
        "1111111.1111111",
        "111111.11111111",
        "11111.111111111",
        "1111.1111111111",
        "111.11111111111",
        "11.111111111111",
        "1.1111111111111",
        "0.11111111111111",
        "0.011111111111111",
        "0.0011111111111111",
        "0.00011111111111111"
    };
    double doubles[] = {
        111111111111110000,
        11111111111111000,
        1111111111111100,
        111111111111110,
        11111111111111,
        1111111111111.1,
        111111111111.11,
        11111111111.111,
        1111111111.1111,
        111111111.11111,
        11111111.111111,
        1111111.1111111,
        111111.11111111,
        11111.111111111,
        1111.1111111111,
        111.11111111111,
        11.111111111111,
        1.1111111111111,
        0.11111111111111,
        0.011111111111111,
        0.0011111111111111,
        0.00011111111111111
    };
    for(int i = 0; i < 22; i++){
        cout 
            << (string2double(strings[i])==doubles[i])
            << " " 
            << (double2string(doubles[i])==strings[i])
            << endl;
    }

    return 0;
}

"为什么要做这个测试?",你可能会问。让我解释一下:一个c++double有52个位来保存一个整数。这个数字的最高值是2^52-1,或4503599627370495。这个数字有16位长。但由于并非所有16位长的数字都能在没有溢出的情况下放入这些位,我的要求是只可靠地转换所有15位长的数。前导或尾随的零不算数,因为它们可以用11个指数位表示。

所以,基本上,我确保所有这些数字理论上都应该适合一个双精度,没有任何溢出,这样我就可以将它们1:1转换回字符串。

现在:你知道有什么函数可以从double转换为string再转换回来,只需打印出"1"就可以完成测试吗?

这基本上是不可能的。有太多的方法可以指定文本格式中的双精度,有关此格式的信息为一旦你转换为替身就输了。例如,在我的机器上,以下所有字符串都转换为相同的双精度:

1
1.0
1e0
1.000000000000000000001
+1.0
0001.0

以及更多。一旦您有替身。

如果你把你的输入限制在一个特定的格式,比如scientific总共只有15位数字,然后最多15位如果您的机器使用IEEE,则应正确往返。