Wiki Double-precision floating-point format说:
这给出了15-17个有效小数位数精度。如果具有最多15位有效数字的十进制字符串转换为IEEE 754双精度表示,然后转换回具有相同有效位数的字符串,则最终字符串应与原始字符串匹配。如果将IEEE 754双精度转换为具有至少17位有效数字的十进制字符串,然后转换回双精度数,则最终数字必须与原始数字匹配。
有人能给我一些例子来说明转换是如何与原作相匹配的,在哪些情况下它不会?
答案 0 :(得分:0)
有15位有效数字,从字符串到双精度数字和后退......
std::istringstream iss("0.123456789012345");
double d;
iss >> d;
std::ostringstream oss;
oss << std::fixed << std::setprecision(15) << d;
std::cout << "should be 0.123456789012345 but might have changed: " << oss.str() << '\n';
注意:对于大约15个有效数字的初始输入字符串,上面的代码可能输出不同的最终字符串。这是一个程序,它试图找到一个15位数的字符串输入,其值不会通过double
转换来保留,而是all values pass for GCC on coliru.stackedcrooked.com。这并不意味着它不会因为不同范围内的其他值而失败。
#include <sstream>
#include <iostream>
#include <iomanip>
int main()
{
int results = 0;
for (unsigned long i = 0; i <= 999999999999999; ++i)
{
std::ostringstream oss;
oss << "0." << std::setfill('0') << std::setw(15) << i;
std::istringstream iss(oss.str());
double d;
iss >> d;
std::ostringstream oss2;
oss2 << std::fixed << std::setprecision(15) << d;
if (oss.str() != oss2.str())
{
std::cout << "from " << oss.str() << '\n' << " to " << oss2.str() << '\n';
if (++results > 50) exit(0);
}
}
}
有17位有效数字,从double到string并返回...
double d = 0.12345678901234567;
std::ostringstream oss;
oss << std::fixed << std::setprecision(17) << d;
std::istringstream iss(oss.str());
double d2;
iss >> d2;
std::cout << "d must equal d2: " << std::boolalpha << d == d2 << '\n';
这应该从不无法从文本表示中恢复相同的double
值。