我在公共 IRC 机器人中使用这个计算器。鉴于 Python 默认使用任意精度,这将允许任何用户执行类似calc 10000**10000**10000
或calc factorial(1000000)
有效地“杀死”机器人的事情。
我想知道是否有某种方法可以避免这种情况。我已经尝试将表达式中的所有术语都转换为浮动,但float(factorial(1000000)
在 Python 解释器中仍然需要很长时间才能完成,而且我不确定多线程方法是否是正确的方法。
我在公共 IRC 机器人中使用这个计算器。鉴于 Python 默认使用任意精度,这将允许任何用户执行类似calc 10000**10000**10000
或calc factorial(1000000)
有效地“杀死”机器人的事情。
我想知道是否有某种方法可以避免这种情况。我已经尝试将表达式中的所有术语都转换为浮动,但float(factorial(1000000)
在 Python 解释器中仍然需要很长时间才能完成,而且我不确定多线程方法是否是正确的方法。
不是一个真正的答案,但我会这样做。您要运行的所有内容都应该在不同的进程中运行。据我所知,不可能限制进程中单个线程的 CPU 使用率或内存使用率。
也就是说,您必须创建一个新进程,与任务一样执行用户输入的内容并将其写入文件,例如。你可以这样做,使用fork
创建一个新文件,PID
并且主进程必须检查直到子进程死亡。一旦进程终止,打开文件“cool_calculator_[pid].out”并将其发送回IRC
.
我想这很简单。
然后使用 ulimit 或其他工具,可以限制子进程,甚至使用主进程杀死它们。如果文件pid
为空,只需回答存在错误或其他问题。我猜你甚至可以写一些错误,比如超出内存或超出 cpu 等。
这完全取决于您要如何杀死不良进程。
最后,您的主进程将负责生成子进程并在需要时杀死它们并发送回答案。
看起来float()
演员阵容毕竟是解决方案。
首先,反三角函数不会在其域之外取值,因此它们是完全安全的,并且可以捕获异常。
>>> acos(5e100)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: math domain error
函数也会发生同样的事情fmod()
。
“正常”三角函数似乎对大值没有任何问题,除非它们真的很大,这使得函数ValueError
再次返回。
舍入函数 (ceil()
和floor()
)round()
工作正常,inf
如果值太大则返回。degrees()
, log()
, log10()
, pow()
, sqrt()
, fabs()
,hypot()
和radians()
函数也是如此。
双曲三角函数和exp()
函数 throwOverflowError
或 return inf
。
该atan2()
功能适用于大值。
对于简单的算术运算,浮点转换使函数抛出一个OverflowError
(或一个inf
)而不是进行计算。
>>> float(10) ** float(100) ** float(100) ** float(1000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OverflowError: (34, 'Numerical result out of range')
>>> float(5e500) * float(4e1000)
inf
最后,有问题的 factorial() 函数。我所要做的就是以迭代的方式重新定义函数并将其添加到safe_dict
.
import sys
def factorial(n):
fact = 1
while (n > 0):
fact = float(fact) * float(n)
n -= float(1)
if float(fact) > sys.float_info.max:
return "Too big"
return str(fact)
print factorial(50e500)
虽然这是一种非常丑陋且效率极低的阶乘计算方式,但足以满足我的需求。其实我觉得我加了很多不必要float()
的s。
现在我需要弄清楚如何将float()
s 放在表达式中的所有术语周围,以便自动发生。