2017-01-28 70 views
-1

我在這行代碼(LL長長整型):獲取浮點異常:8

ll d = (x/((y/1000000) - 1)); 

這似乎是造成這個浮點異常錯誤。 但是,當我將其更改爲:

ll d = (1000000*x)/(y-1000000); 

錯誤消失。簡單的代數會讓你相信它們都是同一件事。

這裏是完整的代碼,這是UVA問題10660,雜貨店。 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=643&page=show_problem&problem=2177

//Problem Link: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=643&page=show_problem&problem=2177 
//Problem type: Complete Search 

#include <iostream> 
#include <vector> 
#include <algorithm> 
#include <climits> 
#include <stdio.h> 
#include <queue> 
#include <set> 
#include <cmath> 
#include <assert.h> 
#include <bitset> 
#include <map> 
#include <unordered_map> 
#include <iomanip> //cout << setprecision(n) << fixed << num 

typedef long long int ll; 
using namespace std; 

int main() { 
    //freopen("output.out", "w", stdout); 
    int cnt = 0; 
    for (int a = 1; a*4 <= 2000; a++) { 
     for (int b = a; a+3*b <= 2000; b++) { 
      for (int c = b; a+b+2*c <= 2000; c++) { 
       ll x = a+b+c; 
       ll y = a*b*c; 
       if (y <= 1000000) continue; 
       //ll d = (x/((y/1000000) - 1)); 
       ll d = (1000000*x)/(y-1000000); 
       if (d < c || x + d > 2000) continue; 
       if (abs((x + d)/100.0 - (y * d)/100000000.0) < 1e-8) { 
        cout << setprecision(2) << fixed << a/100.0 << " " << b/100.0 << " " << c/100.0 << " " << d/100.0 << endl; 
        cnt++; 
       } 
      } 
     } 
    } 
    cout << cnt << endl; 
    return 0; 
} 

如果我將其更改爲ll d = (x/((y/1000000.0f) - 1))然而,然後錯誤消失,但我得到一個錯誤的答案,並在輸出線的數量僅爲717,而應該是949(我不得不穀歌解決這個奇怪問題的答案是:/)

+0

由於整數除以零,您將得到SIGFPE。 – kennytm

+0

我不認爲這是可能的。 「if(y <= 1000000)繼續;」 y永遠不會等於1000000,所以不應該有零除。 – SinByCos

+0

'(x /((y/1000000) - 1))'只要'y/1000000 == 1'就能導致除數爲零。 – kennytm

回答

1

首先,這裏沒有浮點運算:所有內容都以整數(具體來說,long long int s)完成。

這意味着,當y10000001999999之間,包括端值,分割y/1000000的結果將是1。因此,從中減去1將導致零分母,除以零異常。

只有當y等於1000000時,第二個表達式纔會產生相同的結果,但程序將因相同的異常而崩潰。

解決此類問題的訣竅是將分子和分母分開,並且完全用整數(即無浮點數)來執行數學運算。構造一個表示有理數的簡單類應該有助於簡化代碼。

+0

哈!說得通。 :)謝謝 – SinByCos

+0

但爲什麼我得到一個WA與ll d =(x /((y/1000000.0f) - 1)); ? – SinByCos

+1

@SinByCos因爲你進入了混合了long long的浮點數。他們有不同的範圍。 「雙精度」只有52位精度,但範圍要高得多,而「長」精度高達63位,範圍更窄。邊界案例附近的混合數學產生的結果可能與目標嚴重偏離。 – dasblinkenlight