在我的程序中,我必须对无符号整数进行算术运算。
- 变量 a 的范围从 0 到 4294967295。
- 变量 b 的范围从 0 到 32。
当我通过获取 a 和 b 的最大值来检查边界条件时,我得到 0 作为答案,因为当我尝试将 a 和 MAX_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);
}