C语言易错知识点八(整形与浮点型在内存中存储的实质)

news2025/1/22 16:11:25

   整形与浮点型在内存中存储的实质

  当我们在刷抖音或者其他短视频平台时,可能会时不时(总是,我相信大家肯定是不会被外表骗到的那一类人ヾ(●゜ⅴ゜)ノ)刷到各种帅哥美女的视频,或者我们在学校里看到帅哥美女时,如果我们只是看看的话,浮于表面就可以了。但我们如果起了爱慕之心,想要立即就地获得对方的所有资料的时候,我们就不会止于外表,而是会从人品,背景等各个方面看待这个人。

  对于数据的存储也是如此,如果我们只是单纯的想用他们,那么掌握用法就可以了,但如果我们想精进自己,了解数据存储的各个方面,那么就不得不谈到最基本的两个数据类型在内存中的存储实质:整形与浮点型。

        一. 整形在内存中存储的实质

  我们都知道我们的计算机储存数据是存储他的二进制,整数的二进制有三种表示方式,即:原码,补码,反码。三种表⽰⽅法均有符号位和数值位两部分,符号位都是⽤0表⽰“正”⽤1表⽰“负”,⽽数值位最⾼位的⼀位是被当做符号位,剩余的都是数值位。

  正整数的原、反、补码都相同。

  负整数的三种表⽰⽅法各不相同:

  原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。

  反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。

  补码:反码+1就得到补码。

  而对于整形来说:数据存放内存中其实存放的是补码

  这时候就会有好奇心浓的铁汁问到:“那为什么整形是以补码存放到内存中的呢?”

  原因有以下几点:

  1. 使⽤补码,可以将符号位和数值域统⼀处理
  2. 同时,加法和减法也可以统⼀处理(CPU只有加法器)
  3. 此外,补码与原码相互转换,其运算过程是 相同的,不需要额外的硬件电路

那么在了解了整形的存储实质,我们接下来看一个有趣的细节:

4a1adde035cd40c881630445b6ec33c7.png

  我们可以看到a的地址在内存中是倒着放的,这是什么原因呢?

  其实超过⼀个字节的数据在内存中存储的时候,就有存储顺序的问题,按照不同的存储顺序,我们分 为⼤端字节序存储⼩端字节序存储,下⾯是具体的概念:

  1. ⼤端(存储)模式:是指数据的位字节内容保存在内存的地址处,⽽数据的位字节内容,保存在内存的地址处。
  2. ⼩端(存储)模式:是指数据的位字节内容保存在内存的地址处,⽽数据的位字节内容,保存在内存的地址处。 

  上述概念需要记住,⽅便分辨⼤⼩端 d=====( ̄▽ ̄*)b ,这里教大家一个简单记忆的口诀(博主自创,不喜勿喷哦~):

  胸怀大的贤士(大端)喜欢将低价值(低位字节)的东西放在高处(高地址),而将高价值(高位字节)的东西放在低处(低地址),以此与他人无争;

  胸怀小的富人喜欢将高价值(高位字节)的东西放在高处(高地址),而将低价值(低位字节)的东西放在低处(低地址),以此展示自己的富有。

  那我们该如何判断一个机器是大端还是小端存储呢?恒然可以调试看内存分布情况,但如果我们在面试的时候,面试官让我们笔写一段程序来判断呢?

—————— ( *・ω・)✄╰ひ╯————————————

  —————— 分界线我啊是为了让你不要偷看答案的哦~ ————

#include<stdio.h>
int check_sys(int a)
{
	if (*(char*)&a == 1)
		return 1;//是小端
	else
		return 0;//是大端
}
int main()
{
	int a = 1;
	printf("%d", check_sys(a));
	return 0;
}

    看的明了吗,铁汁们?(´・_・`)  ,接下来让博主来简单的解释一下吧:

c772593ea1bd42eaa25cbabc835f858e.png

    解释完了,都懂了吧?○( ^皿^)っHiahiahia… 

e236391162fe4b31aadcd3be3956d9e9.png

    好好好,别骂了别骂了,简单说一下:1 是个整形,占四个字节,将整形 1 强制类型转换为 char* 类型后再取出他的地址 得到的就是第一个字节 ,小端机器中就是01(即1),大端机器中就是00(即0)

  那接下来我们来谈谈浮点数在内存中存储的实质

二.浮点数在内存中存储的实质

  众所周知,浮点数家族包括: float、double、long double 类型。那既然整数是二进制存储的,那么浮点数是不是二进制存储的呢?

  答案是肯定的,那这个时候博主又有坏心思了,问一下各位同志们,5.5的二进制是个啥?

 这里博主就直接给出答案和解释了:5转换成是101,那么5.5的二进制就是101.101。

  f561b040855848039edf86be55abb929.jpeg

  是个人都能看出来答案错了吧^V^(不然博主坏心思加粗的目的是什么)。让我们一步一步来,回到十进制转二进制的方法:第一位的权重是2 ^ 0,第二位是2 ^ 1,那么,小数点后第一位的权重就是 2 ^ (-1),小时点后第二位就是 2 ^ (-2),以此类推,推算可以得到5.5的二进制就是101.1了。

  这时候又有爱动脑筋的铁柱子举一反三了:“既然这样的话,3.3 不就无法用二进制表示了吗?” 我滴妈呀,这都可以被你想到!屏幕前的你也太聪明了吧! 对的,计算机中有些浮点数无法精确保存,3.3 就是其中一个例子。

  好的,本篇博客到此为止,谢谢各位的观看与支持!再见。

——————————————————————

  *´∀`)´∀`)*´∀`)*´∀`) 以为这就结束啦?!怎么可能对吧?没点爆炸性的知识这篇博客还有啥意思。

那就来一道题目呗┏ (^ω^)=☞

#include <stdio.h>
int main()
{
 int n = 9;
 float *pFloat = (float *)&n;
 printf("n的值为:%d\n",n);
 printf("*pFloat的值为:%f\n",*pFloat);
 *pFloat = 9.0;
 printf("num的值为:%d\n",n);
 printf("*pFloat的值为:%f\n",*pFloat);
 return 0;
}

  答案是啥 答案是啥?9 ,9.000000 ,9 ,9.000000?哈!如果你也是这个答案的话那么得好好看,好好学啦! 

  好的,接下来正式讲一下浮点数的存储实质:

  根据国际标准IEEE(电⽓和电⼦⼯程协会) 754,任意⼀个⼆进制浮点数V可以表⽰成下⾯的形式:

• V   =  (−1) ^ S * M * 2 ^ E 

• (−1)S 表⽰符号位,当S=0,V为正数;当S=1,V为负数 

• M 表⽰有效数字,M是⼤于等于1,⼩于2的数

•  2 ^ E 表⽰指数位

  举例来说:

  ⼗进制的5.0,写成⼆进制是 101.0 ,相当于 1.01×2^2 。 那么,按照上⾯V的格式,可以得出S=0,M=1.01,E=2。

  ⼗进制的-5.0,写成⼆进制是 -101.0 ,相当于 -1.01×2^2 。那么,S=1,M=1.01,E=2。

  IEEE 754规定: 对于32位的浮点数,最⾼的1位存储符号位S,接着的8位存储指数E,剩下的23位存储有效数字M ;对于64位的浮点数,最⾼的1位存储符号位S,接着的11位存储指数E,剩下的52位存储有效数字M 

  来个图示意一下:2491d5e8fc904efabee4da59cf69212a.png

5857fe10881c4353b588a6344595c251.png

   而IEEE 754 对有效数字M和指数E,还有⼀些特别规定:

  前⾯说过, 1≤M<2 ,也就是说,M可以写成 1.xxxxxx 的形式,其中 xxxxxx 表⽰⼩数部分。 IEEE 754 规定,在计算机内部保存M时,默认这个数的第⼀位总是1,因此可以被舍去,只保存后⾯的 xxxxxx部分。⽐如保存1.01的时候,只保存01,等到读取的时候,再把第⼀位的1加上去。这样做的⽬ 的,是节省1位有效数字。以32位浮点数为例,留给M只有23位,将第⼀位的1舍去以后,等于可以保 存24位有效数字。

⾄于指数E,情况就⽐较复杂 ⾸先,E为⼀个⽆符号整数(unsigned int)

  这意味着,如果E为8位,它的取值范围为0~255;如果E为11位,它的取值范围为0~2047。但是,我 们知道,科学计数法中的E是可以出现负数的,所以IEEE 754规定,存⼊内存时E的真实值必须再加上 ⼀个中间数,对于8位的E,这个中间数是127;对于11位的E,这个中间数是1023。⽐如,2^10的E是 10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

 除此之外,还有两种特殊情况:E为全0 和 E为全1,其实这就相当于两个极端:我们只需要记住

  1. 当E为全0的时候,这个数接近于无限小,即为0
  2. 当E为全1的时候,这个数接近于无线大 

  ok,那我们来回顾一下刚刚的题目: 

   第一个:第一个打印9应该没问题

   第二个:使用指针强制将整形 9

0000 0000 0000 0000 0000 0000 0000 1001

  转换为浮点型,套刚刚的公式我们可以得到9的E项全为0,那么这个数就是接近无穷小的,打印出来的值就是0.000000。

  第三个:浮点数9.0 等于⼆进制的1001.0,即换算成科学计数法是:1.001×2^3 所以: 9.0  =  (−1)   ∗ 0  (1.001)  ∗  23 , 那么,第⼀位的符号位S=0,有效数字M等于001后⾯再加20个0,凑满23位,指数E等于3+127=130, 即10000010 所以,写成⼆进制形式,应该是S+E+M,即

0 10000010 001 0000 0000 0000 0000 0000

  这个数是多少,不会算?怕啥?俺们程序猿有自己的计算器5a33c5f725df40acb05b580eb4efd520.png   是不是莫名的有一股骄傲油然而生了?

  第四个:打印浮点数9.000000应该也没有什么问题吧?(*゚ー゚)

  aa1269b517474f069dbc94e64c28a75b.png

   对照一下答案,博主没讲错(真好)

   I am better than yesterday, that's enough ————黄色安全帽(抖音)

本篇博客也就到此为止了,送大家一碗鸡汤,勉励自己以及这世界上所有追逐梦想的赤子趁年华尚好努力提升自己,莫欺少年穷!

c8d2be0759fd4184b01271e99cd52641.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1290098.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NFC和蓝牙在物联网中有什么意义?如何选择?

#NFC物联网# #蓝牙物联网# 在物联网中&#xff0c;NFC和蓝牙有什么意义&#xff1f; NFC在物联网中代表近场通信技术。它是一种短距离、高频的无线通信技术&#xff0c;可以在近距离内实现设备间的数据传输和识别。NFC技术主要用于移动支付、电子票务、门禁、移动身份识别、防…

Vue2中v-html引发的安全问题

前言&#xff1a;v-html指令 1.作用&#xff1a;向指定节点中渲染包含html结构的内容。 2.与插值语法的区别&#xff1a; (1).v-html会替换掉节点中所有的内容&#xff0c;{{xx}}则不会。 (2).v-html可以识别html结构。 3.严重注意&#xff1a;v-html有安全性问题&#xff0…

STM32串口接收数据包(自定义帧头帧尾)

1、基本概述 本实验基于stm32c8t6单片机&#xff0c;串口作为基础且重要的外设&#xff0c;具有广泛的应用。本文主要理解串口数据包的发送与接收是如何实现的&#xff0c;重要的是理解程序的实现思路。 2、关键程序 定义好需要用到的变量&#xff1a; uint8_t rxd_buf[4];//…

湖南麒麟下默认使用串口输出系统日志

有时候为了调试方便&#xff0c;需要将系统日志通过CPU的串口进行输出&#xff0c;以下是针对至强E5V4处理器上安装湖南麒麟操作系统后将日志通过串口输出的配置。 首先在bios中打开串口重定向功能&#xff0c;这里的BIOS是AMI的BIOS 内部配置如下&#xff0c;波特率115200配置…

ESP32网络开发实例-发送邮件

发送邮件 文章目录 发送邮件1、邮件发送配置2、软件准备3、硬件准备4、代码实现本文将详细介绍在ESP32中如何使用SMTP协议发送邮件。 1、邮件发送配置 在本次实例中,我们将通过QQ邮箱向指定邮件地址发送邮件。 第一步,注册QQ邮箱 第二步,开启QQ邮箱SMTP/IMAP 服务: 生成…

一文搞懂Git版本控制系统

1. Git简介 当涉及到软件开发或协作时&#xff0c;版本管理是一个不可或缺的概念。无论你是一个独立开发者还是一个团队成员&#xff0c;都会遇到需要跟踪和管理代码变更的情况。这时候&#xff0c;Git作为一个强大而流行的版本控制系统就发挥着重要的作用。 Git&#xff08;读…

使用Pytoch实现Opencv warpAffine方法

随着深度学习的不断发展&#xff0c;GPU/NPU的算力也越来越强&#xff0c;对于一些传统CV计算也希望能够直接在GPU/NPU上进行&#xff0c;例如Opencv的warpAffine方法。Opencv的warpAffine的功能主要是做仿射变换&#xff0c;如果不了解仿射变换的请自行了解。由于Pytorch的图像…

每日一题:LeetCode-75. 颜色分类

每日一题系列&#xff08;day 12&#xff09; 前言&#xff1a; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f50e…

【多线程】线程的三种常见创建方式

文章目录 线程创建方式1——Thread线程创建方式2——Runnable线程创建方式2——匿名内部类线程创建方式3——Callable、FutureTask,带返回值 线程其实是程序中的一条执行路径。 那怎样的程序才是多线程程序呢&#xff1f; 例如12306网站就是支持多线程的&#xff0c;因为同时可…

通过仿真理解信道化接收机分析过程

概要 信道化从子信道带宽划分上可分为临界抽取和非临界抽取两种&#xff0c;从各子信道中心频率布局上可分为偶型排列和奇型排列&#xff0c;从处理流程上可分为信道化分析与信道化综合过程。本文主要通过仿真来理解偶型排列/临界抽取/信道化分析过程。 基本原理 常规的数字…

基于KSZ9897VLAN 虚拟WAN网络接口

目录 1:先看看高通的8327是如何虚拟网络接口 2: Linux 内核中选上802.1Q 3: 实际效果展示 4&#xff1a;配置使用 1:先看看高通的8327是如何虚拟网络接口 rootOpenWrt:~# cat /etc/config/wirelessconfig wifi-device wifi0option type qcawifioption macaddr 68:89:75:04:…

三十九、TCC模式

目录 一、定义 1、需要实现的方法&#xff1a; 2、优点&#xff1a; 3、缺点&#xff1a; 二、原理 1、例子&#xff1a; 2、工作模型图&#xff1a; 3、空回滚和业务悬挂 三、实现TCC模式 1、编写TCC服务接口 2、实现TCC服务接口 一、定义 TCC模式是Translucent Tr…

三焦不通,百病丛生?三焦指的到底是什么?

本 期 导 读 今天来讲一讲&#xff0c;看起来比较古怪的腑——三焦。 三焦的名字虽出于《内经》&#xff0c;但对它的描述却不像其他十一脏腑那么具体&#xff0c;留下了极大的解说空间。 三焦真的不可捉摸吗&#xff1f;当然不是。本文就带你揭开三焦的那层似有还无的面纱…

SQL手工注入漏洞测试(Access数据库)-墨者

———靶场专栏——— 声明&#xff1a;文章由作者weoptions学习或练习过程中的步骤及思路&#xff0c;非正式答案&#xff0c;仅供学习和参考。 靶场背景&#xff1a; 来源&#xff1a; 墨者学院 简介&#xff1a; 安全工程师"墨者"最近在练习SQL手工注入漏洞&#…

YOLOv8改进 | TripletAttention三重注意力机制(附代码+机制原理+添加教程)

一、本文介绍 本文给大家带来的改进是Triplet Attention三重注意力机制。这个机制&#xff0c;它通过三个不同的视角来分析输入的数据&#xff0c;就好比三个人从不同的角度来观察同一幅画&#xff0c;然后共同决定哪些部分最值得注意。三重注意力机制的主要思想是在网络中引入…

社区生鲜店铺线上管理平台,提升店铺运营管理效率的秘密武器

智慧零售是一种基于现代技术的零售模式&#xff0c;通过人工智能、大数据分析和物联网等先进技术的运用&#xff0c;对商品销售、用户需求和市场趋势进行深度分析和预测&#xff0c;从而实现精细化管理和个性化服务。智慧零售不仅可以优化商品的库存管理和运营效率&#xff0c;…

java单人聊天

服务端 package 单人聊天;import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import…

【源码解析】聊聊阻塞队列之BlockingArrayQueue

阻塞队列 阻塞队列&#xff1a;顾名思义 首先它是一个队列&#xff0c;而一个阻塞队列在数据结构中所起的作用大致如下入所示。 当阻塞队列是空时&#xff0c;从队列中获取元素的操作将会被阻塞。当阻塞队列时满的时&#xff0c;往队列里添加元素的操作将会被阻塞。 试图从空的…

【沐风老师】3DMAX切片工具插件安装使用方法详解

3DMAX切片工具安装使用方法 3DMAX切片工具&#xff0c;该工具沿世界坐标轴以规则的间隔对对象进行切片处理。例如&#xff0c;对于快速均匀细分复杂网格、顶点绘制或应用“弯曲”修改器非常有用。 【适用版本】 3dMax2016 - 2023&#xff08;不仅限于此范围&#xff09; 【安装…

Spring Cloud Stream 4.0.4 rabbitmq 发送消息多function

使用 idea 创建 Springboot 项目 添加 Spring cloud stream 和 rabbitmq 依赖 pom文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchem…