2017-10-18 100 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