将地板截断为小数点后三位C++



我想将楼层号截断为 3 位十进制数。例:

input : x = 0.363954;
output: 0.364

我用了

double myCeil(float v, int p)
{
  return int(v * pow(float(10),p))/pow(float(10),p );
}

但是输出是0.3630001.我试图使用<cmath> trunc,但它不存在。

浮点数学通常使用二进制表示形式;因此,有些十进制值不能完全表示为浮点值。试图摆弄内部精度就遇到了这个问题。但大多数情况下,当有人尝试这样做时,他们实际上是在尝试使用特定的精度显示值,这很简单:

double x = 0.363954;
std::cout.precision(3);
std::cout << x << 'n';

你要找的函数是std::ceil,而不是std::trunc

    double myCeil(double v, int p)
    {
        return std::ceil(v * std::pow(10, p)) / std::pow(10, p);
    }

根据需要以std::floorstd::round替换myFloormyRound。 (请注意,std::round显示在 C++11 中,如果尚未启用,则必须启用(。

只是

不可能准确地得到 0.364。您无法将数字 0.364 (364/1000( 完全存储为浮点数,就像您需要无限个小数才能将 1/3 写为 0.3333333333...

你做对了,除了你可能想使用 std::round(( 来舍入到最接近的数字,而不是 int((,它会修剪。

比较浮点数是一项棘手的工作。通常,您能做的最好的事情就是检查数字是否彼此足够接近。

您是否出于比较目的进行四舍五入?在这种情况下,您似乎对 3 位小数感到满意(这取决于所讨论的每个问题......(,在这种情况下,为什么不只是

bool are_equal_to_three_decimals(double a, double b)
{
   return std::abs(a-b) < 0.001;
}

请注意,通过比较四舍五入的数字和我建议的函数获得的结果并不等效!

这是一个旧帖子,但你要求的是二进制数学的十进制精度。 两者之间的转换给你一个明显的区别。

我认为,你的主要观点是关于恒等的,这样你就可以使用两个数字之间的相等/不等式比较。

由于我们人类使用的(十进制(和计算机使用的(二进制(之间存在差异,因此我们有三个选择。

  1. 我们使用十进制库。这在计算上是昂贵的,因为我们使用的数学与计算机的工作方式不同。有几种,有一天它们可能会被性病收养。参见例如"ISO/IEC JTC1 SC22 WG21 N2849">

  2. 我们学习用二进制进行数学运算。这在精神上是昂贵的,因为这不是我们正常做数学的方式。

  3. 我们更改算法以包含身份测试。

  4. 我们更改算法以使用差异测试。

对于选项 3,我们可以决定一个数字需要与另一个数字有多接近才能被视为"相同数字"。

一种简单的方法是(如上面的@SirGuy给出的(我们使用天花板或地板作为测试 - 这很好,因为它允许我们选择我们感兴趣的大量数字。 它是特定于领域的,如果使用 2 的幂而不是 10 的幂,他给出的解决方案可能会更优化一些。

您肯定只想在使用相等/不等式检验时进行计算。

所以现在,我们的相等性测试将是(对于 10 个二进制位置(近 3dp((

// Normal identity test for floats.
// Quick but fails eg 1.0000023 == 1.0000024 
return (a == b);

变为(2^10 = 1024(。

// Modified identity test for floats.
// Works with 1.0000023 == 1.0000024 
return (std::floor(a * 1024) == std::floor(b * 1024));

但这并不好我会选择选项 4。假设您认为任何小于 0.001 的差值都是微不足道的,例如 1.00012 = 1.00011。

执行额外的减法和符号去除,这比位移便宜得多(也更可靠(。

// Modified equality test for floats.
// Returns true if the ∂ is less than 1/10000.
// Works with 1.0000023 == 1.0000024 
return abs(a - b) < 0.0001;

这归结为您关于计算循环性的评论,我建议您计算两个圆之间的增量(差值(,而不是测试等价性。但这并不完全是你在问题中问的......

最新更新