c++ 表示无限大小的方法

c++ 表示无限大小的方法,第1张

先写结论
#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一个代表无限大的数当作"哨兵节点", 于是在往上查询了一下, 有两个方法:

  1. 引入limits.h, 里面有各种不同类型的最大值对应的宏
  2. 直接数字表示, 例如0xFFFF或者65535代表unsigned short的最大值

其实也能用了, 不过我觉得会有敲错一个数字或者敲漏一个f的风险.
于是我想了下觉得利用"~"运算符取反其实还挺方便的.

int

最大值
是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的处理即可

unsigned short

只要说明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;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/578288.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-11
下一篇 2022-04-11

发表评论

登录后才能评论

评论列表(0条)

保存