运行 不使用 Decimal() 时的时间错误

Run time error when Decimal() is not used

我正在尝试解决这个问题question。我的解决方案(如所写)给出运行时错误

    import math
    from decimal import Decimal

    for i in range(int(input())):
        v,r=map(int,input().split())
        x=9.8

        ans=math.degrees(math.asin(r*x/(v*v))/2)
        format_float = "{:.7f}".format(ans)
        print("Case #"+str(i+1)+":",format_float)

但是当我改用 x = Decimal(9.8) 时 - 它被接受了。

这里发生了什么?还有何时或何时不使用十进制。

时间限制:60 秒。 内存限制:1 GB。 1 ≤ T ≤ 4500 , 1 ≤ V ≤ 300 , 1 ≤ D ≤ 10000 , 保证每个测试用例都能解决

您可以使用 Decimalfloat 解决所有三百万个允许的案例,并显示它们的不同之处和方式:

import math
from decimal import Decimal

def f(v, r):
    try:
        x=9.8
        ans=math.degrees(math.asin(r*x/(v*v))/2)
        format_float = "{:.7f}".format(ans)
        return format_float
    except:
        return 'error'
        
def d(v, r):
    try:
        x=Decimal(9.8)
        ans=math.degrees(math.asin(r*x/(v*v))/2)
        format_float = "{:.7f}".format(ans)
        return format_float
    except:
        return 'error'
        
for v in range(1, 301):
    for r in range(1, 10001):
        expect = d(v, r)
        result = f(v, r)
        if result != expect:
            print(f'{v=}  {r=}  Decimal:{expect}  float:{result}')

输出:

v=21  r=45  Decimal:45.0000000  float:error
v=42  r=180  Decimal:45.0000000  float:error
v=63  r=405  Decimal:45.0000000  float:error
v=84  r=720  Decimal:45.0000000  float:error
v=119  r=1445  Decimal:45.0000000  float:error
v=126  r=1620  Decimal:45.0000000  float:error
v=161  r=2645  Decimal:45.0000000  float:error
v=168  r=2880  Decimal:45.0000000  float:error
v=175  r=3125  Decimal:45.0000000  float:error
v=231  r=5445  Decimal:45.0000000  float:error
v=238  r=5780  Decimal:45.0000000  float:error
v=245  r=6125  Decimal:45.0000000  float:error
v=252  r=6480  Decimal:45.0000000  float:error

让我们仔细看看最小的v=21 r=45

x = 9.8
v = 21
r = 45
print(r*x/(v*v))

输出:

1.0000000000000002

因此,由于 float 不精确,您恰好生成了一个大于 1 的数字,asin 然后崩溃了。

在这种情况下避免这种情况的一种方法是在最后一次除法之前一直留在整数域:

r*98/(10*v*v)

使用它,在所有允许的情况下,您将获得与 Decimal 相同的结果。