我正在开发一个程序,我需要知道 C 中带符号整数的确切边界。我的问题是,如果你编译一个依赖于这个边界的程序,你是否必须检查本地环境以查看有多少位用来持有价值?
我会尝试更好地解释这一点。每当我编写一个使用有符号整数的 C 程序,并且该程序的一部分依赖于大数时,我担心一个简单的计算会溢出:比如 4,294,967,296 + 1。会发生什么?这个数字会滚动到负数吗?
它取决于我如何编译程序(换句话说,我用来编译程序的编译器)还是取决于我的 .exe 运行的环境?
谢谢你的帮助!
我正在开发一个程序,我需要知道 C 中带符号整数的确切边界。我的问题是,如果你编译一个依赖于这个边界的程序,你是否必须检查本地环境以查看有多少位用来持有价值?
我会尝试更好地解释这一点。每当我编写一个使用有符号整数的 C 程序,并且该程序的一部分依赖于大数时,我担心一个简单的计算会溢出:比如 4,294,967,296 + 1。会发生什么?这个数字会滚动到负数吗?
它取决于我如何编译程序(换句话说,我用来编译程序的编译器)还是取决于我的 .exe 运行的环境?
谢谢你的帮助!
((sizeof(n) + sizeof(int) - 1) & ~(sizeof(int) - 1))
这应该给你限制
这仅取决于您如何编译程序,即您不需要在运行时检查“环境”。对于任何重要的事情,您应该使用固定大小的整数类型<stdint.h>
,例如int32_t
。
您可以使用 中的常量检查整数类型的范围<limits.h>
,例如INT_MAX
。
标头#include <limits.h>
包含您需要的常量,包括:
CHAR_BIT
- a 中的位数char
。CHAR_MAX
- 普通的最大值char
。SCHAR_MAX
- a 的最大值signed char
。UCHAR_MAX
- 的最大值unsigned char
。SHRT_MAX
- a 的最大值short
。USHRT_MAX
- 的最大值unsigned short
。INT_MAX
UINT_MAX
LONG_MAX
ULONG_MAX
LLONG_MAX
ULLONG_MAX
对于有符号类型,还有最小值:
CHAR_MIN
- 平原char
; 该值可能是 0 或负数。SCHAR_MIN
SHRT_MIN
INT_MIN
LONG_MIN
LLONG_MIN
溢出时无符号算术的行为是完全定义的(产生的值是正确的模数UINT_MAX + 1
或类似的,取决于操作数的类型)。
溢出时带符号算术的行为是未定义的,避免比调查好得多。任何给定的编译器都可以选择任何方式处理它。传统上,溢出时的值经常被包装(添加两个大的正但有符号的整数通常会产生一个负值)。然而,现代 C 编译器不那么宽容。
如果您真的担心溢出,可以使用上面的整数常量来帮助防止溢出。
使用limits.h
标题。它定义了不同类型的最大值和最小值的常量。
比如说 4,294,967,296 + 1。会发生什么?这个数字会滚动到负数吗?
如果您添加该数字,如果未签名,它将翻转为 0。如果将最大正数加 1,无符号整数将翻转到最小负数。