科学记数法转换加倍 - 精度误差

时间:2015-03-09 04:40:41

标签: c++ solaris precision double-precision scientific-notation

我正在编写一段代码,将双值转换为科学记数法,在C ++中精度为15。我知道我可以使用像sprintf这样的标准库和%e选项来做到这一点。但我需要提出自己的解决方案。 我正在尝试这样的事情。

double norm = 68600000;
if (norm)
{
    while (norm >= 10.0)
    {
      norm /= 10.0;
      exp++;
    }
    while (norm < 1.0)
    {
      norm *= 10.0;
      exp--;
    }
}

我得到的结果是

norm = 6.8599999999999994316;
exp = 7

我从question

中澄清了失去这种精确度的原因

现在我尝试将值舍入为15的精度,这将导致

6.859 999 999 999 999

(很明显,由于第16个小数点小于5,我们得到这个结果)

预期答案:标准= 6.860 000 000 000 000,exp = 7

我的问题是,有没有更好的方法可以将双重科学记数法转换为15的精度(不使用标准的libs),这样当我回合时我会得到6.86。如果你注意到这里的问题不在于舍入机制,而是由于与机器epsilon相关的精度损失而使用双倍到科学记数法转换

1 个答案:

答案 0 :(得分:2)

您可以将norm声明为 long double 以获得更高的精度。 long double wiki虽然有一些编译器特定的问题需要注意。有些编译器使double成为double的双重同义词。

解决这个精度问题的另一种方法是使用字符串形式的数字,并为不受机器epsilon影响的字符串实现自定义算术运算。 例如:

int getEXP(string norm){ return norm.length() - 1; };

string norm = "68600000";
int exp = getEXP(norm); // returns 7

下一步是实现函数以将十进制字符插入到范数字符串中的适当位置,并添加您喜欢的任何级别的精度。没有机器epsilon担心。