C语言 乘法和除法无符号整数



在我的程序中,我必须对无符号整数进行算术运算。

  • 变量 a 的范围从 0 到 4294967295。
  • 变量 b 的范围从 0 到 32。

当我通过获取 a 和 b 的最大值来检查边界条件时,我得到 0 作为答案,因为当我尝试将 aMAX_NS 相乘时会发生溢出。理想情况下,我应该得到 7 作为答案。我如何编写程序以处理溢出并得到 7 作为答案,希望它适用于 a 和 b.Thank 的其他有效值范围。

#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);

 }
**

编辑:**请注意,我不能使用未签名的长长。我只能对变量使用无符号的 int。

这是

风向标建议的解决方案

#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);
}

关键是乘积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);
}

最新更新