[英]CodeBlocks C++ Bug
我在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; }
}
有人知道出什么問題嗎?
除非您告訴我們您的“怪異”錯誤是什么,否則我假設這是您的第二段代碼:
不起作用
問題是,您正在比較浮點數,因為pow()
返回floating points
, 請參見pow()
函數的定義 。
由於舍入誤差,浮點數學並不精確。 諸如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
變量類型。
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 overloads
http://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;
> } }
以上內容在VS 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后綴不適用於雙字面量也很正確,因此我也更改了代碼以更正此錯誤。
它也可以在ideone.com上使用! http://ideone.com/3XcY4G
int main()
{
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; }
}
問題是math.h無法正常工作,因此我必須使用cmath。 第二,不是int,而是float或double。
碼:
#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;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.