我正在解决Toph中的问题。在这个问题中,我必须找出其中有2个相等的圆的矩形的空白空间。
#include <stdio.h>
float pi=3.1416;
int main()
{
int i,t;
float r,rest;
scanf("%d",&t);
for(i=1;i<=t;i++)
{
scanf("%f",&r);
rest=(4*r*2*r)-(2*pi*r*r);
printf("Case %d: %.2f\n",i,rest);
}
return 0;
这是我的解决方案。它为第一个测试用例返回正确的值,但无法解决第二个用例。有什么问题???
float pi=3.1416;
是问题的原因。在数学头文件(#include <math.h>
)下,有一个常量M_PI
代替。
编辑:抱歉,未完全阅读,显然问题出在浮点精度上。如果将所有float值更改为double,则应该可以使用。
#include <stdio.h>
double pi=3.1416;
int main()
{
int i,t;
double r,rest;
scanf("%d",&t);
for(i=1;i<=t;i++)
{
scanf("%lf",&r);
rest=(4*r*2*r)-(2*pi*r*r);
printf("Case %d: %.2lf\n",i,rest);
}
return 0;
}
与2和8不同,double
更准确的原因是float
不能代表3.1416以及输入值:
3.1416 -> 3.1415998935699462890625
40.082 -> 40.082000732421875
85.8 -> 85.8000030517578125
根本没有足够的精度,(请注意,IEEE-754 float
(绝大多数用于float
,将其存储在base-2中。)最有可能的是,后来的数字可能是专门生成的,以使测试用例失败。如果想了解更多,请float
和Don’t Store That in a Float。
数值常数是What Every Computer Scientist Should Know About Floating-Point Arithmetic,假设它们的版本为,是精确的(乘以1.7168
。)具有单点精度的最佳可能是r*r
,它与1.7167999744415283203125
相差]。对于2.55584716796875E-8
,它是double
,除以1.71680000000000010373923942097
,再加上输入的值。