浮点精度设置如何工作

How Floating Point precision setting works

本文关键字:工作 何工作 精度 设置      更新时间:2023-10-16

我已经看到了有关如何为浮点数设置精度以及我们在下面做的任何事情的许多答案:

double RoundDouble(double doValue,int nPrecision)
{
    return (floor((doValue*pow(10,nPrecision)+0.5))/pow(10,nPrecision));
}

我不明白将正确设置的精度设置到几乎相等的数字中如何乘以乘以?任何人都可以详细解释

这只是在使用全数字舍入来实现我们在学校学习的所有技巧,以在小数点下切下来:在十进制之后拿起第一n位数字,向上或向下最正确的一个。

如果您在将12.3456到2个小数点舍入到2个小数位置中,那么您自然希望结果为12.35,因为" 4"是两位数的最正确的,并被随后的" 5"舍入围。

现在,要使用数学来实现这一目标,我们利用floor来实现舍入(实际上您可以使用std::round)。但这将使我们达到整个数字,我们将失去所有分数。

为了避免这种情况,我们首先乘以100,将所有有趣的部分移动到整个数字领域:

1234.56

如果您使用std::floor(x+0.5)std::round(x)将此数字围成最接近的整体值,则获得:

1235.0

最后,将其除以100,使您的数字被舍入(是的,请记住我们将其舍入)到两个小数点:

12.35

希望您现在看到呼叫pow的情况。通过将10提高到nPrecision的功率,我们将获得一个缩放因子,在使用此技巧时,将在四舍五入后提供许多小数点。在这种情况下,我们想要2,而pow(10,2)为100。

我自由清理您的功能以获得可读性:

double RoundDouble(double doValue, int nPrecision)
{
    double scale_factor = pow(10.0, static_cast<double>(nPrecision));
    return std::round(doValue * scale_factor) / scale_factor;
}

我尚未实现上面的实现,但是如果我们使用某些示例输入进行调试,那么下面的事情就会发生:

// say we have 5.89162 and we want it to 2 decimal places 5.89 so
RoundDouble(5.89162,2)
{
return (floor(5.89162*pow(10,2)+0.5))/pow(10,2);
/* which will look like
    floor((5.89162x100+0.5)/100)
     floor(589.662/100)
     floor(5.89662)
and floor function will bound it to 5 it means the output will be 5 instead of 5.89*/
}

让我们逐步做。

  1. x = doValue * pow(10, nPrecision) - nPrecision数字移至整体部分,其他位置保持在分形部分;
  2. y = floor(x + 0.5) - 圆形到整体零件(如果x是非负);
  3. z = y / pow(10, nPrecision) - 移动nPrecision数字回到分形部分。

它没有。浮点没有十进制位置。它有二进制位置,它们与十进制位置无关。它所做的只是提供近似值。

有关证明,请参见此处。

如果您要准确地想要十进制位置,则必须使用十进制radix。