对于任何算法问题,允许的错误为10 -6 。
我在第一个解决方案中声明了一个long double
作为变量,并获得了WA。
但是,当我将变量声明为double
时,我得到了AC。
我想知道为什么要做出此决定,因为已知long double
比double
更准确。除了变量,输出方法外,我什么都没改变。
这是我的代码:
#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
。答案 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
,尽管较早的迭代也具有类似的措词)。该标准对浮点类型有此规定(我强调):
共有三种浮点类型:
float
,double
和long 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 double
和wa
的含义) 。但是,由于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;
}