我想知道长双和双之间的区别 [英] I want to know the difference between a long double and a double

查看:170
本文介绍了我想知道长双和双之间的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

For any algorithmic problem, an error of 10-6 is allowed.

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

I declared a long double as a variable in my first solution and got a WA.

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

But, when I declared a variable as double, I got an AC.

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

I want to know why this decision was made because long double is known to be more accurate than double. I have not changed anything except variables, output methods.

这是我的代码:

#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.
  • changing the double to long double; and
  • changing the printf format specifier from f to lf.

推荐答案

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

... long double is known to be more accurate than double.

不,实际上不是.可能是 ,但是绝对不能保证.

No, it's really not. It may be but it's by no means guaranteed.

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

The difference between the two types is detailed in the standard (in this case, C++17 [basic.fundamental]/8, though earlier iterations also have similar wording). The standard has this to say about the floating point types (my emphasis):

共有三种浮点类型:floatdoublelong double.

类型double提供的至少精度与float一样,类型long double提供的至少精度与double一样.

The type double provides at least as much precision as float, and the type long double provides at least as much precision as double.

类型float的值集是类型double的值集的子集; double类型的值集是long double类型的值集的子集.

The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double.

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

The value representation of floating-point types is implementation-defined.

由于子集"包括两个集合完全相同的可能性(A ⊂ A是不言自明的),因此没有实际要求long double具有比<<更大的 范围和/或精度c1>,尽管有时确实如此.

Since "subset" includes the possibility that the two sets are identical (it's axiomatic that A ⊂ A), there's no actual requirement than long double has a larger range and/or precision than double, though it sometimes does.

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

If you want to figure out what the differences are in your implementation, you should be looking into the numeric_limits class in the <limits> header, as per the following demo program:

#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';
}

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

The output on my system is, formatted for readability:

              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 double,我的范围明显更大,并且(大约)还有三位数的精度.

You can see that my range is substantially larger for a long double and there's also (roughly) an extra three decimal digits of precision.

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

In terms of what effect this can have on your code, it's difficult to say since you haven't actually provided an adequate description of what the problem is (specifically what wa and ac mean). However, since a long double may have more precision and/or range than a double, it's certainly conceivable that this may affect how your code behaves.

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

I should also mention that the correct format specifier for a long double is actually %Lf (capitalised L) rather than %lf. That may well be causing a problem for you since, with the test data given on the page you linked to in a comment, I get the correct result for double/%f and long double/%Lf.

但是它会为long double/%lf提供不同的结果(并为此给出gcc警告).

But it gives different results (and a gcc warning, for that matter) for long double/%lf.

这篇关于我想知道长双和双之间的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆