【问题标题】:C++ double rounds up when unwanted不需要时 C++ 双舍入
【发布时间】:2014-12-18 10:42:44
【问题描述】:

我正在用 C++ 编写距离公式的程序。 x1=0 y1=0 x2=1 y2=1 的答案应该是 1.14 左右,但打印出来的答案是 2.00。每个变量都存储为 double 我不知道这里出了什么问题。这是我的代码,感谢您的帮助!!

//  main.cpp
//  Chap6_42
//
//  Created on 10/21/14.
//

#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double distance(double,double,double,double); //distance prototype


int main()
{
    double d = 0;

    double x1 = 0; //coordinate x1
    double x2 = 0; //coord x2
    double y1 = 0; //coord y1
    double y2 = 0; //coord y2




    cout << "Enter four cords (x1,y1,x2,y2) to find the distance between them " << endl;
    cout << "x1 = ";
    cin >> x1;
    cout << "y1 = ";
    cin >> y1;
    cout << "x2 = ";
    cin >> x2;
    cout << "y2 = ";
    cin >> y2;

    d = distance (x2,x1, y2,y1); //calls to distance function, performs computations

    cout << "The distance is " << fixed << setprecision(2) << showpoint << d << endl;



    return 0;
}
double distance(double x2,double x1,double y2,double y1) //distance function header
{

    return sqrt(pow(x2-x1,2.0)) + sqrt(pow(y2-y1,2.0)); //distance function computations


}
                                                //function definition

【问题讨论】:

  • 毕达哥拉斯(因此投反对票)- 抱歉
  • 除了反对票之外,为什么每个人都用“pow(x,2.0)”发布答案。基本上有 3 个错误的答案,因为“pow(-3.0,2.0)”返回“-9.0”,在这种情况下是错误的,因为 Zach 想要毕达哥拉。
  • @DarioOO 这个问题不是那个帖子的重复。这个问题是关于用using namespace std; 污染全局命名空间并导致函数名称解析问题。

标签: c++ types double


【解决方案1】:

为什么你认为答案在 1.14 左右?鉴于您的示例,它应该返回 2.0

sqrt((pow(2.0 - 1.0, 2.0))) + sqrt((pow(2.0 - 1.0, 2.0)))
sqrt((pow(1.0, 2.0))) + sqrt((pow(1.0, 2.0)))
sqrt(1.0) + sqrt(1.0)
1.0 + 1.0
2.0

多田!

如果您正在计算距离,正如函数名称所暗示的那样,您需要调整您的公式。

return sqrt(pow(abs(x2 - x1), 2.0) + pow(abs(y2 - y1), 2.0));

【讨论】:

    【解决方案2】:

    你的计算是错误的。你调用sqrt 两次,而你应该只在整个总和上调用一次。

    return sqrt(pow(x2-x1,2.0) + pow(y2-y1,2.0));
    

    【讨论】:

      【解决方案3】:

      你和毕达哥拉斯在如何计算距离上意见不一

      【讨论】:

        【解决方案4】:

        你的公式是错误的。

        你写道:

        sqrt(pow(x2-x1,2.0)) + sqrt(pow(y2-y1,2.0));
        

        应该是:

        sqrt(pow(x2-x1,2.0) + pow(y2-y1,2.0));
        

        无论如何,不​​要在那里使用pow,而是手动乘法,这(可能)更快更准确。

        sqrt( (x2-x1)*(x2-x1) + (y2-y1)*(y2-y1) );
        

        此外,您通常可以使用平方距离而不是距离来实现小的性能提升。

        【讨论】:

        • 每个人都会遇到。有时走出去,做点别的事,然后重新阅读,就会清除这样的认知障碍。
        • 实际上 pow(-3.0,2.0) 在我的机器上返回 -9.0,在第二个版本中缺少“abs”。或整数参数解决这个问题。 (或手动乘法)
        • @DarioOO:那是......数学库的有趣数学。
        • 真的吗?为什么会这样?这不仅仅是出乎意料,坦率地说,这只是 pow 函数的数学错误。
        • 确实深奥的使用“pow”而不是“var*var”:D 我看到你在最后一分钟添加了“abs”:D
        【解决方案5】:

        鉴于您出于某种深奥的原因打算使用“pow”,您的代码应该是

        return sqrt(abs(pow(x2-x1,2.0)) + abs(pow(y2-y1,2.0)));
        

        return sqrt(pow(x2-x1,int(2)) + pow(y2-y1,int(2)));
        

        如果您要编程,您可能需要大量数学知识。你需要“在纸上”知道你将要使用的算法(即使是简单的算法,比如 Pitagora 的算法)。同样,双精度数的舍入误差不会对结果产生太大影响(除非您使用一些不良的条件算法,否则 Pitagora 并非如此。

        【讨论】:

        • 显然我的答案无缘无故被否决,这并不比其他答案最差。 downvoter,有礼貌并解释你的理由。如果 downvote 是针对“abs”的使用,那么 downvoter 更仔细地阅读 abs 和 pow 真正在做什么,你会看到我的代码正在工作,而当前投票的答案的代码不起作用。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-23
        • 1970-01-01
        • 2011-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多