我在C++ (CodeBlocks)做一些事情,但我发现了一个奇怪的问题。我把我的代码发送给了我的朋友(他在DevC++中测试过),它起了作用。我试过这两种密码:
#include <iostream>
#include <math.h>
using namespace std;
int main() //this function works
{
if (pow(3, 2) + pow(4, 2) == pow(5, 2)) {
cout << "Works" << endl;
} else { cout << "Nope" << endl; }
}但是,然后我像这样更改了主要功能(但它没有工作):
int main() //this function doesn't work
{
int t1 = 3, t2 = 4, t3 = 5;
if (pow(t1, 2) + pow(t2, 2) == pow(t3, 2)) {
cout << "Works" << endl;
} else { cout << "Doesn't work" << endl; }
}有人知道问题出在哪里吗?
发布于 2015-06-05 11:15:34
问题是数学不起作用,所以我不得不使用数学。第二,不是int,而是浮动或加倍。
代码:
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
float t1 = 3, t2 = 4, t3 = 5;
if (pow(t1, 2) + pow(t2, 2) == pow(t3, 2)) {
cout << "PT" << endl;
}
else {
cout << pow(t1, 2) + pow(t2, 2) << endl;
cout << pow(t3, 2) << endl;
}
}发布于 2015-06-03 20:49:51
除非您告诉我们您的“奇怪”错误是什么,否则我假设,您的第二个代码片段打印:
不管用
问题是,您正在比较浮点数,因为pow()返回floating points,函数。
浮点的数学是不准确的,因为舍入误差。像9.0这样的简单值不能精确地用二进制浮点数表示,浮点数字的有限精度意味着操作顺序的微小变化可以改变结果。不同的编译器和CPU体系结构以不同的精度存储临时结果,因此根据环境的详细信息,结果将有所不同。例如:
float a = 9.0 + 16.0
float b = 25.0
if(a == b) // can be false!
if(a >= b) // can also be false!甚至
if( Math.abs(a-b) < 0.00001) // wrong - don't do this这是一个不好的方法,因为选择一个固定的epsilon (0.00001)是因为它“看起来很小”,当比较的数字也很小时,它实际上可能太大了。
我个人使用以下方法,
public static boolean nearlyEqual(float a, float b, float epsilon) {
final float absA = Math.abs(a);
final float absB = Math.abs(b);
final float diff = Math.abs(a - b);
if (a == b) { // shortcut, handles infinities
return true;
} else if (a == 0 || b == 0 || diff < Float.MIN_NORMAL) {
// a or b is zero or both are extremely close to it
// relative error is less meaningful here
return diff < (epsilon * Float.MIN_NORMAL);
} else { // use relative error
return diff / Math.min((absA + absB), Float.MAX_VALUE) < epsilon;
}
}别忘了读关于浮点算法,每个计算机科学家应该知道什么?!
参考: 这是我答案的参考。
编辑:是OP关于C++的问题,下面是nearlyEqual()的编辑版本:
#include <iostream> // std::cout
#include <cmath> // std::abs
#include <algorithm> // std::min
using namespace std;
#define MIN_NORMAL 1.17549435E-38f
#define MAX_VALUE 3.4028235E38f
bool nearlyEqual(float a, float b, float epsilon) {
float absA = std::abs(a);
float absB = std::abs(b);
float diff = std::abs(a - b);
if (a == b) {
return true;
} else if (a == 0 || b == 0 || diff < MIN_NORMAL) {
return diff < (epsilon * MIN_NORMAL);
} else {
return diff / std::min(absA + absB, MAX_VALUE) < epsilon;
}
}
int main(void) {
float t1 = 3.0, t2 = 4.0, t3 = 5.0, epsilon = 0.0000000001; // don't use int here!
if (nearlyEqual((pow(t1, 2) + pow(t2, 2)), pow(t3, 2), epsilon)) {
cout << "Works" << endl;
} else {
cout << "Doesn't work" << endl;
}
return 0;
}产出如下:
作品
编译器: Cygwin C++编译器。
Cygwin版本: 1.7.25
发布于 2015-06-03 19:32:42
变量类型。
double pow (double base , double exponent);
float pow (float base , float exponent);
long double pow (long double base, long double exponent);
double pow (Type1 base , Type2 exponent); // additional overloadshttp://www.cplusplus.com/reference/cmath/pow/
试一试
> int main() {
> double d1 = 3.0, d2 = 4.0, d3 = 5.0;
> if(pow(d1,2) + pow(d2,2) == pow(d3,2)) {
> cout << "Works" << endl;
> }
> else {
> cout << "Nope" << endl;
> } }以上内容也不适用于2013年。
我用了一个函数
bool CheckPyth(double a, double b, double c) {
double aa = pow(a,2);
double bb = pow(b,2);
double cc = pow(c,2);
if(aa + bb == cc) {
return(true);
}
else {
return(false);
}
}这似乎表明,正如CoryKramer指出的,它是一个浮点舍入错误。关于d后缀对双字面值无效的说法也是正确的,所以我也修改了代码以纠正这个错误。
https://stackoverflow.com/questions/30628945
复制相似问题