【C语言】整数,浮点数数据在内存中的存储

news2024/10/5 20:24:48
Tiny Spark get dazzling some day.

目录

  • 1. 整数在内存中的存储
    • 1.1 原码、反码、补码
    • 1.1 大小端存储
      • 1.2.1 字节序分类
      • 1.2.2 判断字节序
  • 2. 浮点数在内存中的存储
    • 2.1 浮点数的存储形式
    • 2.2 浮点数的 “ 存 ”
      • 2.2.1 S
      • 2.2.2 E
      • 2.2.3 F
    • 2.3 浮点数的 “ 取 ”
      • 2.3.1 S
      • 2.3.2 E、F
  • 3. 浮点数存储例题

1. 整数在内存中的存储

1.1 原码、反码、补码

我们都知道,数据在二进制中都是以 二进制 的形式存储在计算机中,而二进制只有 01两个数字。

有符号整数的二进制序列中,最高位 称 符号位,表示正负;其他位 称 数值位,表示数值。
无符号整数的二进制序列中,没有符号位,即每一位 均为 数值位
有多少位具体看 该整数的类型大小,比如 int 类型的

整数 的二进制表示 有三种,分别为 原码反码补码(数据存放在内存中的就是 补码 !)。
整数的三种码都是一样的,负数的则有所不同:

  • 原码 是整数数值直接翻译成 二进制 所得。
  • 反码 是将 原码 的符号位不变,其他数值位按位取反所得。
  • 补码反码 + 1 所得。
  • 若从
    举个例子
  • 整数十进制:-1
  • 原码:1 0 0 0 0 0 0 1
  • 反码:1 1 1 1 1 1 1 0
  • 补码:1 1 1 1 1 1 1 1

1.1 大小端存储

先来看个例子

// 我们在编译器中创造一个变量, 看看它在内存中的存储情况
int a = 0x11223344; // 用十六进制数值对 变量a 进行初始化赋值

开启调试 打开内存监视窗口 看一下
在这里插入图片描述
一开始的时候我也有点懵逼,这里不应该是显示为 11 22 33 44 这样吗?
后来我了解到,当 数据大小 >= 2个字节 ,在内存中存储的时候,就会有 字节序 的问题。
存储顺序 就分为 大端存储小端存储

1.2.1 字节序分类

在这里插入图片描述

在这里插入图片描述

  • 大端存储 :是指数据的 低位字节内容 保存在内存的 高地址 处,而数据的 高位字节内容,保存
    在内存的 低地址 处。
  • 小端存储 :是指数据的 低位字节内容 保存在内存的 低地址 处,而数据的 高位字节内容,保存
    在内存的 高地址 处。

简记:
(内容)(顺序)(内容)(顺序)
大端
小端

那么,我们该如何知道当前机器的字节序呢?

1.2.2 判断字节序

  • 第一种
int check()
{
	int i = 1;
	return (*(char*)&i);
}
int main()
{
	int ret = check();
	if(ret == 1)
	{
		printf("小端存储\n");
	}
	else
	{
		printf("大端存储\n");
	}
	return 0;
}

在这里插入图片描述

  • 第二种
int check()
{
	union // 在联合体中 a 和 b 共用同一块空间
 	{
 		int a;
 		char b;
 	}un;
 	un.i = 1;
 	return un.b;
}
int main()
{
	int ret = check();
	if(ret == 1)
	{
		printf("小端存储\n");
	}
	else
	{
		printf("大端存储\n");
	}
	return 0;
}

在这里插入图片描述


2. 浮点数在内存中的存储

2.1 浮点数的存储形式

上图获取来自百度百科: IEEE 754:浮点数表示

根据上面的资料,那么任意浮点数 V(Value) 可以表示为
在这里插入图片描述

  • (-1) ^ S 表示表示符号位 正负
  • F 表示 大于等于1小于2 的 有效数字
  • 2 ^ E 表示 指数 位(E 是 unsigned int 无符号整数类型)

举例:
十进制数 9.0 转换称二进制为 1001.0,用科学计数法来表示就是 1.001 x 2 ^ 3
那么, S = 0, F = 1.001,E = 3

单精度的浮点数 和 双精度的浮点数 在内存分配的空间是不同的

  • float 类型的浮点数内存分配

在这里插入图片描述

  • double 类型的浮点数内存分配

在这里插入图片描述

2.2 浮点数的 “ 存 ”

2.2.1 S

首个比特位存 S 表示浮点数的 正负(0 或 1)

2.2.2 E

前面我们了解到,E 是一个无符号整数,在 float类型浮点数中有占 8个比特位,取值范围 0 ~ 255,
double类型浮点数中占 11个比特位,取值范围 0 ~ 2047,也就是说 E 是一个非负整数。
但在科学计数法,是允许存在 负数的 E 存在的。

所以,IEEE 754 制定了规定:

E 存入内存时,其真实值必须加上其取值范围的中间数,float类型的为 127,double类型的则为
1023. 比如,2 ^ 8 的 E 是 8,在存入内存时要 + 127 = 135(假设是单精度浮点数类型),即为二进制 10000111

在这里插入图片描述
资料来自百度百科IEEE 754:指数偏差

偏移值就是 内存值(E存入内存值)真实值(E原值) 的差

2.2.3 F

F大于等于1小于2 的,对于任何浮点数都几乎可以表示 1.xxxxxxxxx
“ 存 ” 的时候,F 只存小数部分的 xxxxxxxxx ;在 “ 取 ” 的时候,再把整数部分的 1 加上去

有啥作用?

(假设是单精度浮点数类型)F在存的时候占23位bit,如果把整数的 1 也存进去的话,小数部分能存22位。 但是如果在 “ 存 ”
的时候,F 只存小数部分的 xxxxxxxxx ;在 “ 取 ” 的时候,再把整数部分的 1 加上去,
那就可以节省1位有效数字,小数部分就可以存23位多一位。

2.3 浮点数的 “ 取 ”

2.3.1 S

S (0 或 1)就正常取,是啥取啥就完了

2.3.2 E、F

  • E 不全为 0 或 不全为 1

在这里插入图片描述

这种情况下只要把 E 减去原来加上的中间值127(float)或1023(double)得到真实值的 E
F 把整数部分的 1 加上小数部分即可

  • E 全为 0

在这里插入图片描述

这种情况表示 浮点数是一个接近0的很小的数 或者就是 0
E 减去原来加上的中间值127(float)或1023(double)得到真实值的 E
F 不再加上整数部分的 1 ,而是还原为 0.xxxxxxxxx 的小数

  • E 全为 1
    在这里插入图片描述
    如果 F 全为 0,则表示这是一个 正无穷大负无穷小 的 浮点数(取决于符号位 S
    E 减去原来加上的中间值127(float)或1023(double)得到真实值的 E

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("n的值为:%d\n",n);
 	printf("*pFloat的值为:%f\n",*pFloat);
 	return 0;
}

输出结果是什么?
在这里插入图片描述

为何有这样的变化?

在这里插入图片描述
我们可以看到 指数 E 部分全为0,说明转化后的小数是一个接近0的很小的数,

0.000000000...后面不全为0,但不为0的数也是在非常后面

而我们使用 printf 函数打印浮点数的时候,再没有限定小数位数的情况下, 默认输出小数点后6位
所以我们看到输出结果的第二行就是

*pFloat的值为:0.000000 // 后面的就不输出了

继续往下,为何第二次打印 n 的值,会变得这么大?
在这里插入图片描述
01000001000100000000000000000000 转化为十进制就为 1091567616

  
  
  Stay hungry. Stay Foolish. 饥渴求知,虚怀若愚。
  感谢各位读者支持,虚心请教,如有错漏或可改进点,请任意指出,感激不尽!
  一起进步!


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

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

相关文章

Docker重启容器失败

Bug描述 [rootVM-12-15-centos ~]# docker restart ca1008fbdf25 Error response from daemon: Cannot restart container ca1008fbdf25: driver failed programming external connectivity on endpoint nginx_java (aded2fc7cbfa784b2e6a39e08d3ae2e7d00c13af88879a8fe7c5007…

软件2班20240506

package com.yanyu;public interface JDBC {void getConnection(); }package com.yanyu;public class Mysql implements JDBC{// ALT ENTER // ctrl o 专门 针对 写 父类方法的Overridepublic void getConnection() {System.out.println("正在 了解…

专家解读 | NIST网络安全框架(1):框架概览

随 着信息技术的快速发展&#xff0c;组织面临着越来越严峻的网络安全挑战。NIST网络安全框架&#xff08;NIST Cybersecurity Framework&#xff0c;CSF&#xff09;是一个灵活的综合性指南&#xff0c;旨在协助各类组织建立、改进和管理网络安全策略&#xff0c;以加强网络安…

流畅的python-学习笔记_符合python风格的对象

对象表示形式 查看对象说明&#xff0c;可以通过__repr__和__str__方法&#xff0c;前者主要用于开发者&#xff0c;后者主要用于用户&#xff0c;这两个方法分别对内置函数repr和str函数提供支持 向量类 备选构造方法 classmethod和staticmethod staticmethod用的不是特别…

yum仓库和NFS网络共享服务

一、yum 1.1yum的定义 yum是一个基于RPM包&#xff0c;构建的软件更新机制&#xff0c;能够自动解决软件包之间的依赖关系。解决了日常工作中的大量查找安装依赖包的时间 为什么会有依赖关系的发生 因为linux本身就是以系统简洁为自身优势&#xff0c;所以在安装操作系统的时…

南京观海微电子---电源,从微观角度观看电功率是怎么产生

从微观角度看看无功功率是怎么产生的&#xff0c;在此之前&#xff0c;我们得先知道引起无功功率的元器件是储能器件&#xff0c;主要是电感和电容。 首先&#xff0c;在宏观上&#xff0c;我们知道电感能导致电压超前电流90&#xff0c;可从如下公式推出&#xff1a; 由此可以…

asp.net mvc使用IHttpModule拦截所有请求,包括资源文件

目录 HttpApplication 类 添加App_Code文件夹 MyHttpModel2 Web.config添加配置&#xff0c;在iis模块中生效 项目发布后&#xff0c;察看注册的自定义模块 框架集&#xff1a;.NET Framework 4.7web框架&#xff1a;asp.net mvc 5 HttpApplication 类 HttpApplication 类…

ASP.NET MVC(二) HtmlHelper

强类型 》》》 Form Html.Action() 执行一个Action&#xff0c;并返回html字符串。 Html.ActionLink() 生成一个超链接。 》》》 htmlhelper 扩展方法 /// 扩展方法 三要素 静态类静态方法this 》》》》上面需要引入命名空间&#xff0c; 》》》 不需要引入命名空间 pu…

数据结构:线性表(详解)

线性表 线性表的知识框架&#xff1a; 线性表的定义&#xff1a; 线性表是具有相同数据类型的n(n > 0)个数据元素的有限序列&#xff0c;当n 0时线性表为一个空表。 若用L命名为线性表&#xff0c;则数据集合为L {a1,a2,…,an}&#xff0c;其中a1称为表头元素&#xff0c…

【JAVA入门】Day03 - 数组

【JAVA入门】Day03 - 数组 文章目录 【JAVA入门】Day03 - 数组一、数组的概念二、数组的定义2.1 数组的静态初始化2.2 数组的地址值2.3 数组元素的访问2.4 数组遍历2.5 数组的动态初始化2.6 数组的常见操作2.7 数组的内存分配2.7.1 Java内存分配2.7.2 数组的内存图 一、数组的概…

SAPUI5基础知识1 - 概览,库,支持工具,自学教程

1. SAPUI5 概览 1.1 SAPUI5 SAPUI5是一种用于构建企业级Web应用程序的开发框架。它是由SAP开发的&#xff0c;基于HTML5、CSS3和JavaScript技术。 SAPUI5提供了一套丰富的UI控件和工具&#xff0c;使开发人员能够快速构建现代化、可扩展和可定制的应用程序。 它还提供了数据…

cmake进阶:变量的作用域说明一(从函数作用域方面)

一. 简介 如同 C 语言一样&#xff0c;在 cmake 中&#xff0c;变量也有作用域的概念&#xff0c;本文我们就来聊一聊关于 cmake 中变量作用域的问题。 接下来从三个方面进行介绍&#xff1a;函数作用域、目录作用域以及全局作用域。 二. 函数作用域 我把这个作用域叫做函数…

文献速递:深度学习医学影像心脏疾病检测与诊断---利用深度学习进行动态心脏PET的自动帧间患者运动校正

Title 题目 Automatic Inter-frame Patient Motion Correction for Dynamic Cardiac PET Using Deep Learning 利用深度学习进行动态心脏PET的自动帧间患者运动校正 01 文献速递介绍 OSITRON正电子发射断层扫描&#xff08;PET&#xff09;心肌灌注成像已被证明相较于其他…

LeetCode-741. 摘樱桃【数组 动态规划 矩阵】

LeetCode-741. 摘樱桃【数组 动态规划 矩阵】 题目描述&#xff1a;解题思路一&#xff1a;动态规划&#xff0c;定推初遍举。解题思路二&#xff1a;倒序循环解题思路三&#xff1a;0 题目描述&#xff1a; 给你一个 n x n 的网格 grid &#xff0c;代表一块樱桃地&#xff0…

Android硬件加速hardwareAccelerated支持/不支持的绘图接口

Android硬件加速hardwareAccelerated支持/不支持的绘图接口 Android硬件加速也即在Androidmanifest.xml配置开启GPU渲染&#xff1a; <application android:hardwareAccelerated"true" > 配置后&#xff0c;Android将启用GPU渲染&#xff0c;在trace里面看会…

2023 年全国职业院校技能大赛(高职组)“云计算应用”赛项赛卷 B(容器云)

#需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包及镜像&#xff09;或有问题的&#xff0c;可私聊博主&#xff01;&#xff01;&#xff01; #需要资源&#xff08;软件包…

【一起深度学习——kaggle叶子分类】

kaggle 叶子分类 目的&#xff1a;将叶子进行分类。实现步骤&#xff1a;1、数据处理&#xff1a;2、加载数据3、 定义残差块4、定义Resnet模型。5、定义训练以及评估函数&#xff1a;6、开始训练&#xff1a;7、输出结果&#xff1a; 目的&#xff1a;将叶子进行分类。 实现步…

观测与预测差值自动变化系统噪声Q的自适应UKF(AUKF_Q)MATLAB编写

简述 基于三维模型的UKF&#xff0c;设计一段时间的输入状态误差较大&#xff0c;此时通过对比预测的状态值与观测值的残差&#xff0c;在相应的情况下自适应扩大系统方差Q&#xff0c;构成自适应无迹卡尔曼滤波&#xff08;AUKF&#xff09;&#xff0c;与传统的UKF相比&…

【Qt】按钮类控件

文章目录 1 :peach:Push Button:peach:2 :peach:Radio Buttion:peach:3 :peach:Check Box:peach:4 :peach:Tool Button:peach: 1 &#x1f351;Push Button&#x1f351; 使⽤ QPushButton 表⽰⼀个按钮&#xff0c;这也是当前我们最熟悉的⼀个控件了&#xff0c;QPushButton …

Ubuntu添加非root用户到Docker用户组

前言 首先平常公司的Linux生产环境为了防止误操作导致灾难性问题&#xff0c;一般都不会给我们开发开放root管理员的账号权限。所以平常在Ubuntu的普通用户登录的时候&#xff0c;要操作Dcoker一般都需要带上sudo来提升命令执行权限。为了解决这一问题&#xff0c;我们只需要将…