在C编程中试验函数样式时,我尝试将以下Haskell代码转换为C。
f (0, 0, 0, 1) = 0
f (0, 0, 1, 0) = f (0, 0, 0, 1) + 1
f (0, 1, 0, 0) = f (0, 0, 1, 1) + 1
f (1, 0, 0, 0) = f (0, 1, 1, 1) + 1
f (a, b, c, d) = (p + q + r + s) / (a + b + c + d)
where
p
| a > 0 = a * f (a - 1, b + 1, c + 1, d + 1)
| otherwise = 0
q
| b > 0 = b * f (a, b - 1, c + 1, d + 1)
| otherwise = 0
r
| c > 0 = c * f (a, b, c - 1, d + 1)
| otherwise = 0
s
| d > 0 = d * f (a, b, c, d - 1)
| otherwise = 0
main = print (f (1, 1, 1, 1))
至
#include <stdio.h>
#include <stdlib.h>
#define int const int
#define double const double
double f(int a, int b, int c, int d)
{
if (a == 0 && b == 0 && c == 0 && d == 1)
{
return 0.0;
}
else if (a == 0 && b == 0 && c == 1 && d == 0)
{
return f(0, 0, 0, 1) + 1.0;
}
else if (a == 0 && b == 1 && c == 0 && d == 0)
{
return f(0, 0, 1, 1) + 1.0;
}
else if (a == 1 && b == 0 && c == 0 && d == 0)
{
return f(0, 1, 1, 1) + 1.0;
}
else
{
int p = a > 0 ? a * f(a - 1, b + 1, c + 1, d + 1) : 0;
int q = b > 0 ? b * f(a, b - 1, c + 1, d + 1) : 0;
int r = c > 0 ? c * f(a, b, c - 1, d + 1) : 0;
int s = d > 0 ? d * f(a, b, c, d - 1) : 0;
return (double)(p + q + r + s) / (double)(a + b + c + d);
}
}
int main(void)
{
printf("%f\n", f(1, 1, 1, 1));
return EXIT_SUCCESS;
}
我期望行为完全相同,但是C程序始终输出0.0。使用
f(0, 0, 1, 1)
时,它们都输出0.5,但是每当数字变大时,C版本就根本不起作用。怎么了? 最佳答案
int p = a > 0 ? a * f(a - 1, b + 1, c + 1, d + 1) : 0;
int q = b > 0 ? b * f(a, b - 1, c + 1, d + 1) : 0;
int r = c > 0 ? c * f(a, b, c - 1, d + 1) : 0;
int s = d > 0 ? d * f(a, b, c, d - 1) : 0;
在这里,将
f
的递归调用的结果存储在int变量中时,将被截断为整数。因此,例如,如果a
为1并且f(a-1, b+1, c+1, c+1)
为0.5
,则p
将为0而不是0.5
,因为您不能将0.5
存储在int中。在Haskell代码中,所有变量都是双精度(或者说是小数),因此您应该在C版本中执行相同的操作,并将所有变量和参数声明为
double
。关于c - 用C语言进行函数编程的意外结果,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26327915/