2015-01-20 29 views
0

將浮點數乘以int將導致使用g ++/visual studio的值不正確舍入Bug乘以簡單浮動1000 * 0.01 = 9

當使用double而不是float時,它總能正常工作。

計算也很簡單 - 1000 * 0.01 - 應在10 - 但其9.

樣本程序

#include <iostream> 
#include <stdio.h> 

typedef unsigned long long int64; 
typedef unsigned int  int32; 

int main() 
{ 
    int64 test = 1000 * 0.01f; 
    printf("Test %u\n",test); // Prints 10 

    int64 test2 = 1000; 
    test2 = test2 * 0.01f; 
    printf("Test2 %u\n",test2); // Prints 9 

    int32 test3 = 1000; 

    test3 = test3 * 0.01f; 
    printf("Test3 %i\n",test3); // Prints 9 

    int64 test4 = 1000; 
    test4 = test4 * 0.01; 
    printf("Test4 %u\n",test4); // Prints 10 

    int32 test5 = 1000; 

    test5 = test5 * 0.01; 
    printf("Test5 %i\n",test5); // Prints 10 

} 

輸出

Test 10 
Test2 9 
Test3 9 
Test4 10 
Test5 10 

編譯使用克喘息32位++ main.cpp -o主編

編輯:這只是一個簡單化!

基本上我不使用0.01F

什麼,我做的是一個單位轉換爲另一種,例如我的一個單位是1:100到另一個單位。另一個是1:10或1:1000。

所以我基本上計算unit1/unit2有正確的乘數,如果我想總結2個不同的單位。

在這種情況下,它是1單元= 1000頁免費= 10

所以10/1000 = 0.01 * 1000 = 10

所以,當我想1000件1單元的轉換爲UNIT2應該導致10因爲基本上unit1是1000的基數,unit2是10 base。

+4

[每臺計算機程序員應該知道浮點什麼(http://blog.reverberate.org/2014/09/what-every-computer-programmer-should.html) – 2015-01-20 22:36:48

+0

歡迎浮動點算術。這是因爲表達式的計算結果類似於9.9999991598134(在此組成數字),所以當截斷它時,就是9. – Barry 2015-01-20 22:37:37

+1

當您鍵入'0.01f'時,計算機會看到'0.00999999977648258209228515625' http://coliru.stacked-crooked。 com/a/1c0d5bd0b0272d7d – 2015-01-20 22:38:52

回答

1

歡迎來到浮點數的世界。這裏發生的是0.01f是二進制的重複小數,所以1000 * 0.01f將等於9.99999999...到我記不起來的地方。之後,有整數截斷,所以9.9999... = 9.

爲什麼0.01f重複小數?這是一個浮點的解剖。 http://www.johndcook.com/blog/2009/04/06/anatomy-of-a-floating-point-number/

欲瞭解該主題的更多信息,Computerphile有一個有趣的視頻。

http://www.youtube.com/watch?v=PZRI1IfStY0

+0

我編輯了我的問題 - 我簡化了這個問題 - 我不使用0.01f – Steve 2015-01-20 22:50:57

+0

「爲什麼0.01f是重複小數?」更簡單的答案:因爲0.01是1/100,即1 /(2^2 * 5^2),並且在基數2中,除以5是週期性的。 – Narcolessico 2017-08-03 07:39:38