我想知道长双和双之间的区别

时间:2018-11-01 04:36:59

标签: c++ variables double long-integer

对于任何算法问题,允许的错误为10 -6

我在第一个解决方案中声明了一个long double作为变量,并获得了WA。

但是,当我将变量声明为double时,我得到了AC。

我想知道为什么要做出此决定,因为已知long doubledouble更准确。除了变量,输出方法外,我什么都没改变。

这是我的代码:

#include <iostream>
#include <string>
#include <cmath>
#include <vector>
#include <queue>
#include <deque>
#include <algorithm>

using namespace std;

#define pi 3.141592653589

int main() {
    double x;
    double y;
    double r = 0.0;
    int n;
    double len;
    double ans = 0.0;
    deque<double> dq;

    cin >> n;
    for (int i = 0; i < n; i++) {
        cin >> x >> y;
        len = sqrt(x* x + y * y);
        if (len > r) {
            r = len;
            dq.clear();
            if ((x > 0 && y <= 0) || (x >= 0 && y < 0))
                dq.push_back(360.0 + (90 + atan2(x, y) * 180 * (-1) / pi));
            else
                dq.push_back(90+atan2(x, y) * 180 * (-1) / pi);
        } else if (r == len) {
            if ((x > 0 && y <= 0) || (x >= 0 && y < 0))
                dq.push_back(360 + (90 + atan2(x, y) * 180 * (-1) / pi));
            else
                dq.push_back(90+atan2(x, y) * 180 * (-1) / pi);
        }
    }
    sort(dq.begin(), dq.end());
    if (dq.size() >= 2) {
        for (int i = 0; i < dq.size() - 1; i++) {
            ans = max(ans, dq[i + 1] - dq[i]);
        }
        ans = max(ans, 360 - dq.back() + dq.front());
        printf("%0.6f", ans);
    }
    else
        cout << "360.000000";
}

我所做的唯一更改是:

  • double更改为long double;和
  • printf格式说明符从f更改为lf

3 个答案:

答案 0 :(得分:2)

long double的实现会在编译器和硬件上发生变化。

Visual Studio仅使用long double作为double的同义词。您将需要在Windows上使用intel编译器来利用intel架构或GCC(版本> 4.3)上的扩展精度硬件。来源:https://en.wikipedia.org/wiki/Long_double

如果您想更新问题以包括代码示例或有关编译器和体系结构的详细信息,我可以在答案中添加更多详细信息。但是通常(在Intel上)长双精度使用80位硬件浮点运算。

编辑:我在Sun / Oracle SparcV9 solaris框上运行了Paxdiablo的代码:

              double        long double
           ============    =============
max        1.79769e+308      1.18973e+4932
min        2.22507e-308      3.3621e-4932
lowest    -1.79769e+308     -1.18973e+4932
digits10             15                 33

答案 1 :(得分:2)

  

...长双精度比双精度更精确。

不,实际上不是。可能是 ,但不能保证。

标准中详细说明了这两种类型之间的区别(在本例中为C++17 [basic.fundamental]/8,尽管较早的迭代也具有类似的措词)。该标准对浮点类型有此规定(我强调):

  

共有三种浮点类型:floatdoublelong double

     

类型double至少提供 精度,float类型提供至少 精度精度为long double

     

类型double的值集是类型float的值集的子集; double类型的值集是double类型的值集的子集。

     

浮点类型的值表示形式是实现定义的。

由于“子集”包含两个集合完全相同的可能性(long double是不言自明的),因此没有实际要求,而A ⊂ A的范围是更大和/或精度要高于long double,尽管有时确实如此。

如果您想弄清楚实现中的区别是什么,请按照以下示例查看double标头中的numeric_limits类程序:

<limits>

my 系统上的输出经过格式化,以提高可读性:

#include <iostream>
#include <limits>
using namespace std;

int main() {
    numeric_limits<double> lim_d;
    numeric_limits<long double> lim_ld;

    cout << "\nmax " << lim_d.max() << " " << lim_ld.max()
         << "\nmin " << lim_d.min() << " " << lim_ld.min()
         << "\nlowest " << lim_d.lowest() << " " << lim_ld.lowest()
         << "\ndigits10 " << lim_d.digits10 << " " << lim_ld.digits10
         << '\n';
}

您可以看到,对于 double long double ============ ============= max 1.79769e+308 1.18973e+4932 min 2.22507e-308 3.3621 e-4932 lowest -1.79769e+308 -1.18973e+4932 digits10 15 18 ,我的范围要大得多,而且(大约)还有三位数的精度。


关于这可能对您的代码产生什么影响,很难说,因为您实际上并未提供关于问题所在的充分描述(特别是long doublewa的含义) 。但是,由于ac可能比long double具有更高的精度和/或范围,因此可以肯定的是,这可能会影响代码的行为。

我还应该提到,double的正确格式说明符实际上是long double(大写的%Lf)而不是L。这很可能会给您带来问题,因为在注释中链接的页面上给出的测试数据中,我得到了%lf / double%f /的正确结果long double

但是对于%Lf / gcc,它给出了不同的结果(并为此发出long double警告)。

答案 2 :(得分:-2)

通过使用此代码,您可以轻松地理解长双精度数应该是双精度的两倍。

#include<iostream>
using namespace std;
main()
{
cout<<"size of double is "<<sizeof(double)<<" bytes"<<endl;
cout<<"size of long double is "<<sizeof(long double)<<" bytes";
return 0;
}