警示,卡精度题的一些坑


用 double 转 LL 的方法提高精度时,需要注意一些问题

浮点损失的原因

  • 浮点位数超过double或者long double存储上限,这个比较常见,这里不作讨论。

  • 浮点数是二进制表示的,但总有二进制无法完美表示的浮点数。虽然 IEEE754 怎么算的我已经忘了。这里主要讨论这个原因

double转long long

面对精度要求较高的题目,一个常见的做法是把double转成long long来运算,比如scanf("%lf", &x); ll a = x*10000

但是这样做是有问题的
1
2
3
4
double x;
scanf("%lf", &x);
ll d = x * 10000;
printf("%lld\n", d);
input
1
1.001
output
1
10009

解决方法

  • 换一个读入方式,比如字符串读入
  • 使用d = round(x * 10000)来替代d = x * 10000,虽然二进制不能完美表示浮点数,但是它会做到尽可能接近,使用round基本不会出问题

ABC#191 D

这个题把我卡的人都差点昏过去,原来我以前的doublelong long写法一直都有问题