奇怪的 C 程序行为
Weird C program behaviour
我有以下 C 程序:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
int main() {
const int opt_count = 2;
int oc = 30;
int c = 900;
printf("%d %f\n", c, pow(oc, opt_count));
assert(c == (int)(pow(oc, opt_count)));
}
我是 运行宁 MinGW Windows 8.1。 GCC 版本 4.9.3。我编译我的程序:
gcc program.c -o program.exe
当我 运行 它时,我得到这个输出:
$ program
900 900.000000
Assertion failed: c == (int)(pow(oc, opt_count)), file program.c, line 16
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
这是怎么回事?我希望断言通过,因为 900 == 30^2.
谢谢!
编辑
我没有使用任何分数或小数。我只使用整数。
当 pow
的实施是通过
时会发生这种情况
pow(x,y) = exp(log(x)*y)
其他库实现首先将指数减少整数次幂,从而避免了这个小的浮点错误。
更多涉及的实施包含
等步骤
pow(x,y) {
if(y<0) return 1/pow(x, -y);
n = (int)round(y);
y = y-n;
px = x; powxn = 1;
while(n>0) {
if(n%2==1) powxn *= px;
n /=2; px *= px;
}
return powxn * exp(log(x)*y);
}
与通常的分而治之。整数幂 powxn
.
的减半 n 平方方法
你从@LutzL 那里得到了一个很好的答案(和解决方案),另一个解决方案是将差异与 epsilon 进行比较,例如:0.00001
,这样你就可以使用标准函数 pow
包含在 math.h
#define EPSILON 0.0001
#define EQ(a, b) (fabs(a - b) < EPSILON)
assert(EQ((double)c, pow(oc, opt_count)));
我有以下 C 程序:
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
int main() {
const int opt_count = 2;
int oc = 30;
int c = 900;
printf("%d %f\n", c, pow(oc, opt_count));
assert(c == (int)(pow(oc, opt_count)));
}
我是 运行宁 MinGW Windows 8.1。 GCC 版本 4.9.3。我编译我的程序:
gcc program.c -o program.exe
当我 运行 它时,我得到这个输出:
$ program
900 900.000000
Assertion failed: c == (int)(pow(oc, opt_count)), file program.c, line 16
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
这是怎么回事?我希望断言通过,因为 900 == 30^2.
谢谢!
编辑
我没有使用任何分数或小数。我只使用整数。
当 pow
的实施是通过
pow(x,y) = exp(log(x)*y)
其他库实现首先将指数减少整数次幂,从而避免了这个小的浮点错误。
更多涉及的实施包含
等步骤pow(x,y) {
if(y<0) return 1/pow(x, -y);
n = (int)round(y);
y = y-n;
px = x; powxn = 1;
while(n>0) {
if(n%2==1) powxn *= px;
n /=2; px *= px;
}
return powxn * exp(log(x)*y);
}
与通常的分而治之。整数幂 powxn
.
你从@LutzL 那里得到了一个很好的答案(和解决方案),另一个解决方案是将差异与 epsilon 进行比较,例如:0.00001
,这样你就可以使用标准函数 pow
包含在 math.h
#define EPSILON 0.0001
#define EQ(a, b) (fabs(a - b) < EPSILON)
assert(EQ((double)c, pow(oc, opt_count)));