【发布时间】:2015-03-17 17:03:59
【问题描述】:
出于有趣的目的,我正在尝试做一个“1-liner”,但由于某种原因,我无法使代码正常工作。注意:这是 C,而不是 C++,但问题仍然存在。
“展开”版本:
#include <stdio.h>
#include <math.h>
int main() {
double iter = 1;
double res = 0;
double elem = 0;
double fib_c = 1;
double fib_p = 1;
double power = 4;
double fact = 1;
while (iter < 15) {
fib_c += fib_p; //fibonacci current
fib_p = fib_c - fib_p; //fibonacci previous
fact *= iter; //factorial
power *= 4; //power of 4
elem = (fib_c * power * sqrt(iter+1)) / fact; //element of series
res += elem; //series
printf("----\nelem = %2.3f\nres = %2.3f\n", elem, res);
iter++;
}
return 0;
}
这是一个系列(我不知道用英语表示它的数学术语),这里element 从 45 上升到 1264,然后又下降到 47。
这是我正在尝试制作的“包装”版本:
#include <stdio.h>
#include <math.h>
int main() {
double iter = 1;
double res = 0;
double elem = 0;
double fib_c = 1;
double fib_p = 1;
double power = 4;
double fact = 1;
while (iter < 15) {
res += (elem = (fib_c += ((fib_p = fib_c - fib_p)) * (power*=4) * sqrt(iter+1)) / (fact*=iter));
printf("----\nelem = %2.3f\nres = %2.3f\n", elem, res);
iter++;
}
return 0;
}
这里element 在不到 5 次迭代中超过了整数。很明显,有些事情是错误的。但是什么?
顺便说一句,如果我每次迭代都打印出每个值(fib_c、power、fact),我将看到正确的值(当前斐波那契数、4 的幂、相应的持续阶乘)。所以我猜测“幕后”发生了一些奇怪的事情,我不知道如何管理它。
有什么想法吗?
【问题讨论】:
-
不要写这样的代码,它是不可维护的,而且附带的好处是不会发生奇怪的未定义行为。快速浏览一下,您正在修改
fib_c并在同一序列点内读取它,这是经典的 C 未定义行为。见Why are these constructs (using ++) undefined behavior?。 -
正如我所说,“为了好玩”。没有人会在我之后维护代码。
-
@ohyou 未定义的行为不好玩,所以 Shafik 的观点是站得住脚的 ;)
-
@ShafikYaghmour 它正在读取 fib_c 以确定要存储到其中的值。
-
@ShafikYaghmour 这对分析有何影响?
fib_c的两次读取(一个来自+=和一个来自fib_p = fib_c - fib_p)作为分配给fib_c的值的计算的一部分发生。第二次读取也是计算分配给fib_p的值的一部分,不会改变任何东西。
标签: c++ c algorithm micro-optimization