我正在阅读保罗格雷厄姆的垃圾邮件计划,并希望更好地理解它,但我的LISP真的很生疏.他有一段代码可以计算概率:
(let ((g (* 2 (or (gethash word good) 0)))
(b (or (gethash word bad) 0)))
(unless (< (+ g b) 5)
(max .01
(min .99 (float (/ (min 1 (/ b nbad))
(+ (min 1 (/ g ngood))
(min 1 (/ b nbad)))))))))
Run Code Online (Sandbox Code Playgroud)
我的问题有两个:(1)是否存在将LISP转换为其他语言的Web资源?(我的偏好是基于C的语言)或失败(2)有人可以为我重写C#中的代码片段吗?
我认为它是这样的(警告,可能的错误.这个片段是作为指导,而不是解决方案):
var g = 2 * (gethash(word, good) | 0);
var b = gethash(word, bad) | 0;
if( (g + b) >= 5)
{
return Math.Max(
0.01,
Math.Min(0.99,
Math.Min(1, b / nbad) /
(Math.Min(1, g / ngood) + Math.Min(1, b / nbad))));
}
Run Code Online (Sandbox Code Playgroud)
再加上Gonzola的答案,不要忘记Lisp提供了无限精度的整数和有理数,而C#喜欢截断.您需要首先将'nbad'和'ngood'转换为浮动以获得可比较(但不完全相同)的结果.
您可能还希望将整个转换后的程序放在已检查的区域中.C#甚至没有对fixnum溢出发出警告 - 第一个近似是将溢出视为内存受限(在Lisp中,如果溢出的数字太大而无法适应剩余的内存,类似的行为结果).
checked {
var fbad = (double)nbad;
var fgood = (double)ngood;
var g = 2 * (gethash(word, good) | 0);
var b = gethash(word, bad) | 0;
if( (g + b) >= 5)
{
return Math.Max(
0.01,
Math.Min(0.99,
Math.Min(1, b / fbad) /
(Math.Min(1, g / fgood) + Math.Min(1, b / fbad))));
}
}
Run Code Online (Sandbox Code Playgroud)