2016-05-09 57 views
2

我遇到了一個我無法弄清楚的問題。以下是演示問題的一些玩具Ç代碼:相同的代碼+二進制在不同的機器上給出不同的結果

for(int i = 0; i < 10000; i++) 
{ 
    float theta = 2*PI*i/N; 
    double s1 = sin(theta); 
    double c1 = cos(theta); 

    float s3 = s1; 
    float c3 = c1; 

    float s2 = sin(theta); 
    float c2 = cos(theta); 

    printf("theta - %f, (s1:%f, c1:%f) (s2:%f c2:%f) (s3:%f c3:%f) diff (s3-s2:%.8f c3-c2:%.8f)\n", theta, s1, c1, s2, c2, s3, c3, s3-s2, c3-c2); 
} 

我已經用gcc和我'運行在兩臺機器上相同的二進制編譯這個(兩人都英特爾處理器,但不同的型號)。由於它是相同的二進制代碼,我期望得到同樣的結果,但這種情況並非如此:

例如,在機#1,這是出於一個提出:

theta - 2.441646, (s1:0.644177, c1:-0.764876) (s2:0.644177 c2:-0.764876) (s3:0.644177 c3:-0.764876) 
diff (s3-s2:0.00000006 c3-c2:-0.00000006) 

而上機#2:

theta - 2.441646, (s1:0.644177, c1:-0.764876) (s2:0.644177 c2:-0.764876) (s3:0.644177 c3:-0.764876) 
diff (s3-s2:0.00000000 c3-c2:0.00000000) 

我有兩個問題:

  • 在機#1,爲什麼不S2/S3和C2/C3匹配?
  • 更重要的是(對於我的應用程序,我需要這兩臺機器產生相同的結果,並且這些精度差異會導致更大的差異,因爲它們會在其他表達式中進一步使用),爲什麼結果在機器中保持一致?它是相同的二進制文件,那麼導致差異的處理器也是如此?其他一些數學庫?

我會喜歡一些解釋,指出我在正確的方向,謝謝〜

+2

我建議你先檢查gcc標誌,關於快/精確數學第一。然後看看生成的彙編代碼是合理的 –

+0

浮點 - 你必須喜歡它。 –

+0

如果您需要更多數字的一致結果,請考慮使用'double'。 –

回答

0

有幾個因素可能影響上述結果,如

  1. 如果兩個CPU模態有相同的指令集;
  2. 如果兩個操作系統都是32位或64位;
  3. 如果您安裝了相同版本的運行時庫,
  4. 或別的東西...

所以,從理論上講,如果他們是一樣的,結果應該是一樣的...

相關問題