无穷大常量
int型变量的取值范围:[-2^31, 2^31 - 1] -> [-2147483648, 2147483647]
0x7fffffff = 2147483647
= (2^31 - 1)
= (1 << 31) - 10x3fffffff = 1073741823
= (2^30 - 1)
= (1 << 30) - 10x3f3f3f3f = 1061109567
0x7fffffff
在十进制表示下,0x7fffffff = 2147483647,恰好等于int型变量的上界,所以在一些情况下用0x7fffffff表示无穷大是一个很好的选择。
但是对于很多情况,设置无穷大为0x7fffffff并不能满足我们的需求。因为对于无穷大,加上一个数应该还是无穷大。而在计算机中,0x7fffffff加上一个数后会溢出,不仅不再是无穷大,还可能是负数。
准确来说,0x7fffffff不能满足“无穷大加一个有穷的数依然是无穷大”这个条件,它会变成了一个很小的负数。
0x3fffffff
显然需要换个数来表示无穷大,这次我们选择 0x3fffffff,这个数用十进制表示是(1 << 30) - 1。因为一般场合下程序中的数据都是小于1e9的,而0x3fffffff = 1073741823 > 1e9。那么这个数不仅满足了比程序中的任何数都大,而且0x3fffffff + 0x3fffffff = (1 << 31) - 2小于int型的边界(1 << 31) - 1 = 2147483647,所以也满足了无穷大加上一个数还是无穷大。
0x3f3f3f3f
除了用0x3fffffff表示无穷大之外,我们还经常能看到用 0x3f3f3f3f 表示无穷大。和0x3fffffff一样,一般场合下的数据都是小于1e9的,而0x3f3f3f3f = 1061109567 > 1e9。0x3f3f3f3f + 0x3f3f3f3f = 2122219134 < int型的边界(1 << 31) - 1 = 2147483647,也满足无穷大加上一个无穷大还是无穷大。
但它有一点比0x3fffffff要好。如果要对一个数组全部赋值无穷大时,使用循环赋值不如使用memset赋值快。memset是按字节赋值的,它能够对数组清零 memset(arr, 0, sizeof(arr))(因为0的每个字节都是0);或者全部赋值-1 memset(arr, -1, sizeof(arr))(-1在计算机中的表示形式为111 … ,每个字节都是11111111);由于0x3f3f3f3f的每个字节都是0x3f!所以要把一段内存全部设置为无穷大时,我们只需要 memset(arr, 0x3f, sizeof(arr))。
总结
概括一下就是:
0x7fffffff = 2147483647,恰好等于int型变量的上界。加数后会溢出
0x3fffffff,0x3f3f3f3f,满足无穷大加上一个无穷大还是无穷大。但0x3f3f3f3f,每个字节都是0x3f可以直接使用memset(arr, 0x3f, sizeof(arr))赋值。