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

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.hqwc.cn/news/671947.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

爱普生S2D13V52快速实现车载显示屏高分辨率显示系统

随着时代的发展&#xff0c;汽车驾驶位前中央的显示屏承担的功能也越来越多&#xff0c;从一开始仅仅是显示仪表盘的信息&#xff0c;再到作为显示屏辅助倒车&#xff0c;再到如今和一块平板一样可公认娱乐&#xff0c;显示屏的大小有些时候成为了一辆车够不够好的体现。随着汽…

【前端】HTML基础(3)

文章目录 前言一、HTML基础1、表格标签1.1 基本使用1.2 合并单元格 2、列表标签2.1 无序列表2.2 有序列表2.3 自定义列表 3、 表单标签2.1 form标签2.2 input标签2.3 label标签2.4 select标签2.5 textarea标签 4、无语义标签5、HTML特殊字符 前言 这篇博客仅仅是对HTML的基本结…

Apache POI入门学习

Apache POI入门学习 官网地址 excel中使用到的类读取excel表格内容表格内容maven依赖方式一测试结果 方式二测试结果 向excel中写入数据方式一方式二方式三测试结果 从 Excel 工作表中的公式单元格读取数据测试结果 Excel 工作表中写入公式单元格从受密码保护的Excel中读取数据…

2024年03月 Scratch 图形化(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch图形化等级考试(1~4级)全部真题・点这里 一、单选题(共18题,共50分) 第1题 运行程序后,角色一定不会说出的数字是?( ) A:2 B:4 C:6 D:8 答案:A 程序中随机数的取值最小为 2,最大为 20 ,那么随机数加上 2 之后的结果的最小值为 4 ,最大值为 22 。所…

查看微信小程序主包大小

前言 略 查看微信小程序主包大小 在微信开发者工具右上角找到“详情->基本信息” 查看微信小程序主包构成 通过微信开发者工具中的“代码依赖分析”工具查看

第十三章 计算机网络

这里写目录标题 1.网络设备2.协议簇2.1电子邮件(传输层)2.2地址解析(网际层)2.3DHCP(动态主动配置协议)2.4URL(统一资源定位器)2.5IP地址和子网掩码 1.网络设备 物理层&#xff1a;中继器&#xff0c;集线器(多路中继器) 数据链路层&#xff1a;网桥&#xff0c;交换机(多端口…

Java常用5大集合类详解(实战)

文章目录 1、Collection1.1 iterator 迭代器 2、List 有序集合2.1 ArrayList ⭐2.2 LinkedList2.3 Queue 3、Set 无序集合3.1 HashSet ⭐3.2 TreeSet3.3 LinkedHashSet 4、Map 键值集合4.1 HashMap ⭐4.2 TreeMap / LinkedHashMap 5、工具类5.1 Collections5.2 Arrays 【拓展】…

多组间比较散点图+误差棒(自备)

目录 数据 计算四分位值 作图 数据 rm(list ls()) library(ggplot2) library(dplyr) library(ggpubr) library(reshape2) library(tidyverse)data <- iris##鸢尾花数据集 dat <- data[,c(5,1)]#单个数据进行分析 计算四分位值 #根据分组计算四分位及中位数 dat1 …

SegFix:预测边界和预测方向来修正边界

论文标题&#xff1a;SegFix: Model-Agnostic Boundary Refinement for Segmentation 论文地址&#xff1a;https://arxiv.org/pdf/2007.04269.pdf 代码地址&#xff1a;https://github.com/openseg-group/openseg.pytorch 两种loss监督 八种方向变回归问题为分类问题 代码地…

GitOps介绍

基础设施即代码 IaC 在理解 GitOps 之前&#xff0c;需要先理解什么是基础设施即代码。 基础设施即代码&#xff08;Infrastructure as Code&#xff0c;简称IaC&#xff09;是一种软件工程实践&#xff0c;它将基础设施的管理和配置过程像管理代码一样进行版本控制、自动化和…

电源小白入门学习7——USB充电、供电、电源路径管理

电源小白入门学习7——USB充电、供电、电源路径管理 USB充电系统需要考虑的因素开关充电和线性充电充电路径管理输入限流路径管理&#xff08;动态功率管理&#xff09;理想二极管帮助提高电池利用率输入过充抑制 上期我们介绍了锂离子电池的电池特性&#xff0c;及充电电路设计…

websevere服务器从零搭建到上线(二)|Linux上的五种IO模型

文章目录 阻塞 blocking非阻塞 non-blockingIO复用 IO multiplexing信号驱动 signal-driven异步 asynchronous拓展知识 看过上篇文章英国基本能理解本文五张图的内容websevere服务器从零搭建到上线&#xff08;一&#xff09;&#xff5c;阻塞、非阻塞、同步、异步 本文要能够在…