C++无符号数比较大小

在代码中看到如下代码:

static constexpr Timestamp MAX_DURATION = 0x7000000000000000;

static bool TimestampGT(Timestamp t_0, Timestamp t_1) {
  return t_0 - t_1 < MAX_DURATION && t_0 != t_1;
}
说明:Timestamp类型为std::uint64_t  即无符号64位整型,t_0与t_1为两个测量时间戳,差值不会很大。
概念:系统时间timestamp为模块处理完的时间,测量时间measured_timestamp 为传感器的观测时间,
他们的数据类型均为Timestamp

在计算机内部,无符号数和其它类型一样,统一都是按照补码加减法规则计算的(毕竟所有的数都是按照补码存放的)而唯一不同的是,最后的结果的解释方式不同。0x7000000000000000代表16进制数,其中0x为前缀(或者用H作为后缀表示16进制数),它转化为二进制数正好是64位数(4×16=64)。
1、当t_0 - t_1 < 0
t_0 - t_1 的二进制数补码最高位必为1(当解释为有符号数时,这个1仅代表负数的意思),即t_0 - t_1 的值在计算机中存储为1_ _ _ _ ,而0x7000000000000000作为无符号数在计算机中存储为0111 _ _ _ _,此时上面的t_0 - t_1 < MAX_DURATION会为false

2、当t_0 - t_1 > 0
t_0 - t_1 的二进制补码最高位为0,即t_0 - t_1 的值在计算机中的存储为0_ _ _ _ ,而0x7000000000000000作为无符号数在计算机中存储为0111 _ _ _ _,此时上面的t_0 - t_1 < MAX_DURATION可能会为true(t_0 - t_1二进制值补码的第二位为0时),也可能为false(t_0 - t_1二进制值的第二位至第五位均为1时,但此时两个测量时间不会相差这么大,实际中不会出现这种情况)

#include <iostream>
int main()
{
	static constexpr std::uint64_t MAX_DURATION = 0x7000000000000000;
	std::uint64_t a =        46116860184274000000;
	std::uint64_t b =        0;

	std::cout<<"\n";
	if( (a - b) < MAX_DURATION  &&  a  !=  b) {
    	std::cout<<"a>b";
    } else {
        std::cout<<"a<b";
        }
	return 0;
} 
结果:a<b  # 实际上a>b
#include <iostream>

int main()
{

static constexpr std::uint64_t MAX_DURATION = 0x7000000000000000;
std::uint64_t a =        1607484021513236;
std::uint64_t b =        1607484021450288;

std::cout<<"\n";
if( (a - b) < MAX_DURATION && a != b){
    std::cout<<"a>b";
    }else{
        std::cout<<"a<b";}

	return 0;
} 
结果a>b
计算机基础知识点:

(1)16进制、二进制转换
十六进制数转换为二进制数的步骤:每一位十六进制数,转换为四位二进制数。
例如:
3A7.B1H
=11 1010 0111.1011 0001 B
注意16进制的表示法,用字母H后缀表示,比如BH就表示10进制数11;也可以用0X前缀表示,比如0X23就是16进制的23,十进制的35(2*16+3=35)。
二进制数转换为十六进制数的步骤:
在向左(或向右)取四位时,取到最高位(最低位)如果无法凑足四位,就可以在小数点的最左边(或最右边)补0,进行换算。例如:
(1001101010.01101)2
=(0010 0110 1010.1110 1000)2
=26A.E8H

(2)-1的 补码
首先把-1的绝对值求出来,等于1,
然后求1的原码(也就是它的二进制):0000 0000 0000 0001,
然后按位取反(每个位上的0变成1,1变成0):1111 1111 1111 1110;
最后加1:1111 1111 1111 1111,
好了,这就是-1的补码了

即步骤如下:
先求正数的原码,
然后按位取反,再加一。
-1二进制存储的特点: -1 的二进制存储 是 全一。

(3)无符号数加减如何实现
在这里插入图片描述

(4)为什么有符号数0XFFFF FFFF代表-1?
0XFFFF FFFF 如果代表一个unsigned int 数据 那么它的值就是 4 294 967 295也就是 无符号整型所能表示的最大值。 0XFFFF FFFF 如果代表一个signed int 数据 那么它的最左边的一位是1,即它必定是一 个负数。这个值是-1. 为什么?
1.C语言里的数据在内存中的表示,数据会因为读取的方式不同而导致读取出来的结果不同。 同样的数据如果按照int和char来读,结果是不同的,如果按照有符号和无符号来读,结果也 可能不同。
2.C语言的数据在内存中用二进制来表示,由于无符号的数据不用腾出最左边的一位来表示正负, 正是由于多出来这一位,我们知道这相当于二进制中的把数据左移一位,扩大二倍。所以无符号 的数据能存储的数值范围要比有符号数大一倍。 3.虽然C语言把数据使用二进制在内存中表示,但是还有一点:计算机是用补码来存储数据的。 即一个数将其转换成为二进制之后还要再转换成补码,才是最终在内存中的样子。
所以上面的问题就有了答案: 0X FFFF FFFF 如果是一个有符号的数字,因为它的最高位是1,所以这个数是个负数。简单的 在内存中的存储形式为 1111 1111 1111 1111 1111 1111 1111 1111,这个是补码,那么原码是 什么呢?根据规则我们知道将上面的数减去二进制的1,即减去0000 0000 0000 0000 0000 0000 0000 0001,得到 1111 1111 1111 1111 1111 1111 1111 1110,然后按为取反,得到0000 0000 0000 0000 0000 0000 0000 0001,这就是原码----即数字的二进制表示方式,这个数字就是-1了。

1为负 0为证
最大正数 0x7FFF 0111
最大负数 0xFFFF 1111
最小负数 0x8000 1000

参考:https://blog.csdn.net/is01753/article/details/74912530

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值