2017-10-18 120 views
2

在我的程序中,我必須對無符號整數執行算術運算。乘除法除無符號整數

  • 變量a具有從0到32

的範圍爲0〜4294967295

  • 變量b具有範圍當我通過取maximun值用於檢查邊界條件和b,我得到0作爲答案,因爲溢出發生在我試圖乘以aMAX_NS。理想情況下,我應該得到7作爲答案。如何編寫程序,使溢出是照顧和我得到7作爲答案,並希望它適用於其他有效值範圍爲a和b.Thanks。

    #include "stdio.h" 
    
    #define MAX_NS 1000000000 
    
    int main() 
    { 
        unsigned int a = 4294967295; 
        unsigned int b = 32 ; 
    
        unsigned int c = ((b * MAX_NS)/a); 
        printf("%d",c); 
    
    
    } 
    

    **編輯:**請注意,我不能使用unsigned long long.I只能使用unsigned int作爲變量。

  • +1

    通過使用'unsigned long long'?您除以最大無符號值,因此在'unsigned int'範圍內的所有結果(除了一個)都將爲'0'。 –

    +0

    如果計算是使用任意大小的中間體執行的,則無法單獨使用操作順序來獲得相同的結果。可能有一些技巧可以針對輸入值(最簡單:c = 7;'),但除此之外,最好的做法是明確提升到更廣泛的類型,比如'uintmax_t'。 –

    +0

    我不明白你爲什麼期望答案是7.完全精確的答案將有五個低位全零,並且高於所有一個的32位。你如何得到7? –

    回答

    1

    這裏是解決方案風向標建議

    #include "stdio.h" 
    
    #define MAX_NS 1000000000 
    
    int main() 
    { 
        unsigned long long a = 4294967295; 
        unsigned long long b = 32; 
    
        unsigned long long c = ((b * MAX_NS)/a); 
        printf("%llu", c); 
    } 
    
    +0

    無論如何,但你是對的,應該是llu – vlada

    +0

    但即使我使用較小的'a'值(假設50000000),我沒有得到正確的答案。應該是640,但我得到了38.可能是什麼原因? –

    +0

    其他的東西一定是問題。我檢查了這段代碼,它打印出7. – vlada

    0

    最關鍵的是,該產品b * MAX_NS必須使用足夠寬的數學計算。

    確保至少有一個*操作數是unsigned long long

    足夠大的b和足夠小的a,商需要更寬的類型以避免溢出;

    #include "stdio.h" 
    // #define MAX_NS 1000000000 
    #define MAX_NS 1000000000LLU 
    
    int main(void) { 
        unsigned int a = 4294967295; // type may remain unsigned 
        unsigned int b = 32 ;   // type may remain unsigned 
    
        unsigned long long c = ((b * MAX_NS)/a); 
        printf("%llu",c); 
    } 
    

    或者,乘以1ull輕微乘法。一般情況下要避免像在(unsigned long long) b * MAX_NS中鑄造。蠻橫鑄造的做法有時令人驚訝縮小數學可能會在稍後發生在這裏uintmax_t b

    #define MAX_NS 1000000000 
    
    int main(void) { 
        unsigned int a = 4294967295; // type may remain unsigned 
        unsigned int b = 32 ;   // type may remain unsigned 
    
        unsigned long long c = ((1ull * b * MAX_NS)/a); 
        printf("%llu",c); 
    } 
    
    +0

    謝謝你的答案,但我們的硬件只支持32位,不能使用無符號long long .. –

    +0

    @GopalaKrishna即使是一個8位處理器也可以支持'unsigned long long'。兼容的C編譯器將形成實現64位類型和數學的必要指令。像「只用到32位數學」這樣的不尋常的要求應該放在_original_文章中。 – chux