#define MY_INT_MAX ( ~0u >> 1 ) //有符号整型的最大值
#define MY_UINT_MAX (~0) //无符号整型的最大值
#define MY_SHORT_MAX ( (unsigned short)~0 >> 1 ) //有符号短整型的最大值
#define MY_USHORT_MAX ( (short)~0 ) //无符号短整型的最大值
#define MY_INT_MIN (-MY_INT_MAX-1) //有符号整型最小值, 或者 (1 << 31)
#define MY_SHORT_MIN (-MY_SHORT_MAX-1) //有符号短整型最小值, 或者 (1 << 15)
正文
在刷leetcode的时候有一个需求,需要append一个代表无限大的数当作"哨兵节点", 于是在往上查询了一下, 有两个方法:
- 引入limits.h, 里面有各种不同类型的最大值对应的宏
- 直接数字表示, 例如0xFFFF或者65535代表unsigned short的最大值
其实也能用了, 不过我觉得会有敲错一个数字或者敲漏一个f的风险.
于是我想了下觉得利用"~"运算符取反其实还挺方便的.
最大值
是4字节*8位=32位, 直接打印了下~0, 结果为会把最后一位符号位的1也反转过来, 这很合理, 但是在做右移运算(~0 >>1)想把符号位的1去掉的时候, ~0代表32位全1, 由于默认是int类型, 恰好是1的补码, 即-1, -1右移还是-1,具体可以看下下面的链接 :
http://t.csdn.cn/zNAOT
所以应该来一个类型说明为无符号整型, 让最高位也能跟着一起右移, 那0后面跟个u就好了(~0u >> 1), 就是代表0x7FFF FFFF.
最小值
首先来看个引用
C语言中,int若是规定大小为两个字节,则其最小值就是-32768。
原因是:
两个字节是16位,规定第一位为符号位,则其能表示的数值范围是-215~215-1,即-32768~32767。
但最小值为什么是-32768,为什么不是-32767呢?
原来人们发现若是在内存中直接存放数的原码,则0000 0000 0000 0000和1000 0000 0000
0000分别表示+0和-0,其值都是0,用两个值表示同一个值,这样太浪费空间了。
于是人们最后决定在内存中存放数的补码,这样+0和-0的存放形式就都是0000 0000 0000 0000了,但是同时也多出来一个1111
1111 1111 1111,它并不是任何一个数的补码,于是将其规定为-32768。
这样表示的话,正数最大值是32767,负数最小值是-32768。
从 0到 32767,用二进制是从:00000000到01111111 。
从-1到-32768,用二进制是从:11111111到10000000 。
也就是说, 在符号型的类型下, 最高位为1, 其余为0, 就代表是最小值, 那就是(1 << 31)就可以了哈哈, 不过我不想写31这么具体的数字, 还可以怎么表示呢, 因为引用里说到原本+0和-0都是表示0, 但由于后来规定了-0为负的max-1来利用多一位, 所以负数比正数多了一位, 那就是可以写成 (-INT_MAX-1)了.
unsigned int那这个好办, 直接~0, 32全1就完事了
short最大值
那就只管16位, 接着像int那样处理就行.
short没有像数字加u就代表unsigned int的后缀, 那来个强制转型就可, 那在反转0的时候, 就只反转16位变为1, 右移一位即可.
最小值
类似int的处理即可
只要说明0是短整型即可, 然后反转16位皆为1, 完事.
测试代码展示先放结果, 下图结果依次是int_max, uint_max, short_max, ushort_max.
#include
#if 0
//来自 limits.h
#define MB_LEN_MAX 2 /* max. # bytes in multibyte char */
#define SHRT_MIN (-32768) /* minimum (signed) short value */
#define SHRT_MAX 32767 /* maximum (signed) short value */
#define USHRT_MAX 0xffff /* maximum unsigned short value */
#define INT_MIN (-2147483647 - 1) /* minimum (signed) int value */
#define INT_MAX 2147483647 /* maximum (signed) int value */
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
#define LONG_MIN (-2147483647L - 1) /* minimum (signed) long value */
#define LONG_MAX 2147483647L /* maximum (signed) long value */
#define ULONG_MAX 0xffffffffUL /* maximum unsigned long value */
#endif
#define MY_INT_MAX ( ~0u >> 1 ) //有符号整型的最大值
#define MY_UINT_MAX (~0) //无符号整型的最大值
#define MY_SHORT_MAX ( (unsigned short)~0 >> 1 ) //有符号短整型的最大值
#define MY_USHORT_MAX ( (short)~0 ) //无符号短整型的最大值
#define MY_INT_MIN (-MY_INT_MAX-1) //有符号整型最小值
#define MY_SHORT_MIN (-MY_SHORT_MAX-1) //有符号短整型最小值
using namespace std;
class Test {
public:
//二进制打印, 模板方法自适应不同类型
template<typename T> static void BinaryPrint(T num) {
printf("\n0x%X\n",num);
for (int i = 4*8-1; i >= 0; i--) {
cout << ((num & (1 << i)) ? 1 : 0);
if (i % 4 == 0) {cout << " ";}
}
cout << " -> " << num << endl;
}
};
int main(int argc, int** argv) {
int a = MY_INT_MAX;
Test::BinaryPrint(a);
unsigned int b = MY_UINT_MAX;
Test::BinaryPrint(b);
short c = MY_SHORT_MAX;
Test::BinaryPrint(c);
unsigned short int d = MY_USHORT_MAX;
Test::BinaryPrint(d);
a = MY_INT_MIN;
Test::BinaryPrint(a);
c = MY_SHORT_MIN;
Test::BinaryPrint(c);
return 0;
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)