打印
[牛人杂谈]

int型整数在内存中的存储方式

[复制链接]
1397|20
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小明的同学|  楼主 | 2018-12-19 14:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
int类型在内存中的方式
起因:话说楼主在写一个将string类型转化为int类型的函数,就是把atoi()这个函数重写一下,当考虑到溢出这种情况的时候,写下了这样一行代码:
if((!minus&&num>0x7fffffff)||(minus&&num<ffffffff)){
    num=0;
    break;
}
注:bool minus 是判断该数字是正还是负。

等到测试的时候发现输入一个负数的字符串,得到的结果居然是0。
我敏锐的发掘,一定是num=0这句起了作用,但是按说不应该进入这个if语句啊。
于是我开始分析,int类型是带符号的类型,即第一位是符号位,当符号位为0的时候表示正数,当符号位为1的时候表示负数,那我输入的应该没错啊,0xffffffff不应该是十进制数2147483647这个数的负数模式-2147483647么??
楼主不解,于是开始试验。
    int i=0xffffffff;
    cout << i;
输出结果:-1
我就震惊了,明明应该是那么多位的负数,而且这么多个f就给我个-1,我真想问电脑你是怎么想的。后来我看了一下书,书上类似的判断用的是
minus&&num<80000000
于是我有些下了下面的代码
    int i=0x80000000;
    cout << i;
输出结果:-2147483648


沙发
小明的同学|  楼主 | 2018-12-19 14:20 | 只看该作者
好吧,看来书上是对的,也不知道电脑是怎么想的怎么翻译的?
于是我开始认真思考这个问题,电脑是怎么想的,发明c++语言的人是怎么想的,以及为什么?
上学的时候隐约记得好像和加法还有减法有关。
于是拿出纸笔,开始模拟。
首先我把int 1和int -1相加,即0x0000001+0xffffffff,诶,奇迹来了,结果是0x100000000,大家看好是9个16进制位哦,而按照int型的存储空间应该是8个16进制位,即4个字节,于是
就剩下0x00000000,这不正好是0么!于是楼主虎躯一震,继续试验。
如果是int 1减去int -1呢?
即0x00000001-0xffffffff这咋减?于是楼主联想上面的例子,决定在整数前面补1位,即0x100000001-0xffffffff得到的结果正好是0x00000002。于是我服了,人家发明的人想的果然就比我们多啊,你想啊,如果是这样就不用进行符号转化了啊,否则,如果按照我之前的理解,-1是0x80000001的话,1+(-1)就应该是先把-1转化为+1,再做加法即0x00000001+0x00000001=0x00000002,这样的话处理起来太麻烦了,而且遇到正数和负数的处理过程不一样大大影响效率。

好了上面的分析分析完了,接下来我说说其他的拓展心得。
1.如果你看见了一个类似0xfffffffa怎么判断它是负几呢?很简单,用0x100000000-0xfffffffa得出来的数加个负号就是了。
2.如果想将一个int型整数取反直接使用符号“~”然后再+1即可,这个方法在效率上比使用符号块,因为是位操作,比运算符操作要快。
如:a=~a+1

使用特权

评论回复
板凳
antusheng| | 2018-12-19 17:24 | 只看该作者
不同变量类型定义数的方式不同,比如最高位是0还是1的问题。

使用特权

评论回复
地板
天灵灵地灵灵| | 2018-12-20 15:13 | 只看该作者
能否用这种方法判断大小端?

使用特权

评论回复
5
heisexingqisi| | 2018-12-20 21:49 | 只看该作者
研究研究这个,对C语言学习还是很有帮助的。

使用特权

评论回复
6
xuanhuanzi| | 2018-12-20 23:06 | 只看该作者
PC里和单片机里好像还是不同的,不同厂家的单片机貌似设计的也不同。

使用特权

评论回复
7
xuanhuanzi| | 2018-12-20 23:06 | 只看该作者
不知道GCC和KEIL,IAR是不是也有这个区别。

使用特权

评论回复
8
zhuomuniao110| | 2018-12-21 23:38 | 只看该作者
以前学习时候,学过这个,后来工作用的时候,发现没用过。

使用特权

评论回复
9
643757107| | 2018-12-21 23:49 | 只看该作者
小数的存储我一直不懂

使用特权

评论回复
10
yiyigirl2014| | 2018-12-22 00:04 | 只看该作者
睡觉了,明天试试。

使用特权

评论回复
11
玛尼玛尼哄| | 2018-12-23 00:33 | 只看该作者
貌似可以用指针观察一下怎么存的。

使用特权

评论回复
12
稳稳の幸福| | 2018-12-23 00:39 | 只看该作者
大年纪的Bool值都是假的吧。

使用特权

评论回复
13
wowu| | 2019-1-7 13:13 | 只看该作者
这样做不对啊  应该是无符号数

使用特权

评论回复
14
heimaojingzhang| | 2019-1-8 11:27 | 只看该作者
定义为无符号类型

使用特权

评论回复
15
dongnanxibei| | 2019-1-8 14:37 | 只看该作者
数据格式要用对。

使用特权

评论回复
16
dongnanxibei| | 2019-1-8 14:37 | 只看该作者
选择变量类型很重要。

使用特权

评论回复
17
xuanhuanzi| | 2019-1-9 09:38 | 只看该作者
C语言的数据类型要求很严格的。

使用特权

评论回复
18
whtwhtw| | 2019-1-11 09:19 | 只看该作者
本帖最后由 whtwhtw 于 2019-1-11 09:27 编辑

计算机用的是补码模式,正数的补码和源码一样,负数是补码模式!!!,负数表现格式为符号位1;后面数为反码+1。

使用特权

评论回复
19
whtwhtw| | 2019-1-11 09:34 | 只看该作者
0XFFFFFFFF的二进制是1111 1111 1111 1111 1111 1111 1111 1111,表示为32位有符号数据就是(-)[111 1111 1111 1111 1111 1111 1111 1111],中括号中是补码+1的结果,我们先-1得[111 1111 1111 1111 1111 1111 1111 1110],这是反码,我们再求反得[000 0000 0000 0000 0000 0000 0000 0001]。所以实际表示的数据就是-1。

使用特权

评论回复
20
whtwhtw| | 2019-1-11 09:40 | 只看该作者
计算机中是分+0和-0的,并规定他们相等,所以有符号的0x00000000和0x80000000是相等的

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

135

主题

1425

帖子

2

粉丝