C语言深入探索浮点数的使用秘密

目录
  • 一、内存中的浮点数
  • 二、浮点数存储实例
  • 三、浮点类型的秘密
  • 四、小结

一、内存中的浮点数

浮点数在内存的存储方式为:符号位,指数,尾数

类型 符号位 指数 尾数
float 1位(第31位) 8位(第23--30位) 23位(第0--22位)
double 1位(第63位) 11位(第52--62位) 52位(第0--51位)

注:float 与 double 类型的数据在计算机内部的表示法是相同的,但由于所占存储空间的不同,其分别能够表示的数值范围和精度不同。

二、浮点数存储实例

浮点数的转换

  • 将浮点数转换成二进制
  • 用科学计数法表示二进制浮点数
  • 计算指数偏移后的值

注意:计算指数时需要加上偏移量,而偏移量的值与类型有关。

示例:对于指数6,偏移后的值如下:

float:127 + 6 -> 133

double:1023 + 6-> 1029

实数 8.25 的在内存中的 float 表示

8.25的二进制表示:1000.01 -> 1.00001 * (2 ^ 3)

  • 符号位:0
  • 指数:127 + 3 -> 130 10000010
  • 小数:00001

内存中 8.25 的 float 表示:

  • 0 10000010 00001000000000000000000 -> 0x41040000

下面看一下 8.25 是不是在内存中表示为 0x41040000 吧:

#include <stdio.h>

int main()
{
    float f = 8.25;
    unsigned int* p = (unsigned int*)&f;
    printf("0x%08X\n", *p);
    return 0;
}

下面为输出结果:

三、浮点类型的秘密

首先看一下 int 类型和 float 类型的范围:

int 类型的范围:[-2 ^ 31,2 ^ 31 - 1]

float 类型的范围:[-3.4 * 10 ^ 38,3.4 * 10 ^ 38]

这就出现一个问题:int 和 float 都占4个字节的内存,为什么 float 却比 int 的范围大得多呢?

解释如下:

  • float 能表示的具体数字的个数与 int 相同
  • float 可表示的数字之间不是连续的,存在间隙
  • float 只是一种近似的表示法,不能作为精确数使用
  • 由于内存表示法相对复杂,float 的运算速度比 int 慢得多

注意:double 与 float 具有相同的内存表示法,因此 double 也是不精确的。由于 double 占用的内存较多,所能表示的精度比 float 高。

下面看一段 float 类型的不精确示例代码:

#include <stdio.h>

int main()
{
    float f = 3.1415f;
    float fl = 123456789;
    printf("%0.10f\n", f);
    printf("%0.10f\n", fl);
    return 0;
}

下面为输出结果:

这个示例就是表示 f 和 fl 小数点的后 10 位,结果表明,float 只是一种近似的表示法,不能作为精确数使用以及float 可表示的数字之间不是连续的,存在间隙。

四、小结

  • 浮点类型与整数类型的内存表示法不同
  • 浮点类型的内存表示更复杂
  • 浮点类型可表示的范围更大
  • 浮点类型是一种不精确的类型
  • 浮点类型的运算速度较慢

到此这篇关于C语言深入探索浮点数的使用秘密的文章就介绍到这了,更多相关C语言浮点数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C语言中魔性的float浮点数精度问题

    从一个问题引入 如果你以前接触过C语言,那么对下面的这段代码一定很熟悉: #include <stdio.h> int main(void) { float f_num1 = 21.75; float f_num2 = 13.45; printf("f_num1 = %f\n", f_num1); printf("f_num2 = %f\n", f_num2); printf("f_num1 + f_num2 = %f\n", f_n

  • C语言如何把浮点数转换为字符串

    目录 把浮点数转换为字符串 1.把float/double格式化输出到字符串 2.注意事项 整型.浮点型和字符串间转换 1.整型.浮点型-->字符串 2.字符串-->整型.浮点型 把浮点数转换为字符串 1.把float/double格式化输出到字符串 标准的C语言提供了atof函数把字符串转double,但是没有提供把float/double转换为字符串的库函数,而是采用sprintf和snprintf函数格式化输出到字符串. 函数声明: int sprintf(char *str, cons

  • C语言菜鸟基础教程之单精度浮点数与双精度浮点数

    上节课 简单介绍了浮点数.计算机程序中的浮点数分为单精度浮点数和双精度浮点数. 单精度和双精度精确的范围不一样. 计算机里的最基本的存储单位用位(bit)来表示.bit只能用来存储0或1. 稍大一点的单位是字节(Byte,简写为B). 再大一级的是千字节(kilo Bytes),用k来表示. 再大一级的单位是兆字节(Mega Bytes),用M来表示.一张照片的大小通常为1~3M. 再大一级的单位为G.一部高清电影的大小通常为1~2G. 再大一级的单位为T. 换算关系为: 1B = 8bit 1

  • C语言入门之浮点数

    实际开发中使用double,而不使用float  浮点数的输出 float采用%f占位符. double采用%lf占位符.测试结果证明,double不可以用%f输入,但可以用%f输出,但是不建议采用%f,因为不同的编译器可能会有差别. long double采用%Lf占位符,注意,L是大写. 浮点数输出缺省显示小数点后六位. 浮点数采用%lf输出,完整的输出格式是%m.nlf,指定输出数据整数部分和小数部分共占m位,其中有n位是小数.如果数值长度小于m,则左端补空格,若数值长度大于m,则按实际位

  • 一篇文章带你了解C语言浮点数之间的比较规则

    目录 你认为这段代码输出什么? 为什么不等于呢? 应该怎么解决? 那么怎么判断两个浮点数 f1 和 f2 相等呢. 伪代码 可以简化为 >> 怎么判断浮点数等于0? 还有一个问题 总结 你认为这段代码输出什么? int main() { float f1 = 1.1; float f2 = 2.2; if (f2 - 1.1 == f1) printf("等于"); else printf("不等于"); return 0; } 答案是不等于. 为什么不

  • C语言中浮点数的精度丢失问题解决

    目录 一 先来看一段代码 运行结果: 二 如何解决 (1)浮点数的大小比较 (2)含浮点数的表达式和0.0的比较 总结 一 先来看一段代码 #include<stdio.h> int main() { double test=0.1; printf("%.100lf",test); return 0; } 运行结果: 直接从现象说结果:精度丢失由于计算机二进制转化过程中因为比特位过多发生数据的截断导致的,这个结果是可以偏大也可以偏小的. 解释一下:首先要知道二进制转换为十进

  • C语言数据(整数、浮点数)在内存中的存储

    本篇主要讨论:整数.浮点数在内存中是怎么保存的! 数据类型详细介绍 在前面C语言基础概览中,已经提到过了基本的C语言内置类型,但C语言的数据类型有无数种~ 但是可以把这些类型分为几个大类: 类型的归类: 存整数的 char,short,int,long,long long及所配套的unsigned,int*,int[]- 2.存浮点数的 float,double,float[]- 结构体(结构体在内存中的存储后面在进行讨论~) 整数在内存种的存储: 1.字节序 2.补码 内存窗口 调试模式下的内

  • C语言中的浮点数据类型

    目录 1. 处理带小数的数值 2. 浮点类型 3. 浮点类型的sizeof 1. 处理带小数的数值 我们来讨论一下类似于1.234567,0.00001,这类非整数的数据.我们先试试看,int能不能装这些数据呢? #include <stdio.h> int main() { int a = 1.234567; int b = 0.00001; int c = 365.12345; printf("%d\n", a); printf("%d\n", b)

  • C语言深入探索浮点数的使用秘密

    目录 一.内存中的浮点数 二.浮点数存储实例 三.浮点类型的秘密 四.小结 一.内存中的浮点数 浮点数在内存的存储方式为:符号位,指数,尾数 类型 符号位 指数 尾数 float 1位(第31位) 8位(第23--30位) 23位(第0--22位) double 1位(第63位) 11位(第52--62位) 52位(第0--51位) 注:float 与 double 类型的数据在计算机内部的表示法是相同的,但由于所占存储空间的不同,其分别能够表示的数值范围和精度不同. 二.浮点数存储实例 浮点数

  • C语言深入探索数据类型的存储

    目录 数据类型介绍 类型的基本归纳 整型家族 浮点数家族 构造类型 指针类型 空类型 整型在内存中的存储 原码,反码,补码 大小端 浮点数在内存中的存储 浮点数存储的规则 数据类型介绍 首先,对于我们C语言中的数据类型,大家应该都有一个清晰的认识吧!如果不记得也没有关系哦~ 在这里来跟着小刘同学回顾一下吧! 关于数据类型,我们在前面已经学习过了一些内置数据类型,以及它们所占的内存空间的大小,例如: char         //字符数据类型int          //整型short      

  • C语言深入探索动态内存分配的使用

    目录 一.动态内存分配的意义 二.malloc 和 free 三.关于 malloc(0) 四.calloc 和 realloc 五.小结 一.动态内存分配的意义 C语言中的一切操作都是基于内存的 变量和数组都是内存的别名 内存分配由编译器在编译期间决定 定义数组的时候必须指定数组长度 数组长度是在编译期就必须确定的 需求:程序运行的过程中,可能需要使用一些额外的内存空间 二.malloc 和 free malloc 和 free 用于执行动态内存分配和释放 malloc 所分配的是一块连续的内

  • C语言深入探索之单链表与typedef的用法

    目录 前言 详解typedef关键字 含义 具体使用 详解单链表参数形式 指针知识补充 单链表形参详解 单链表实战案例 完整代码实现 详解头插建表 运行效果 前言 昨天博主去本站问答贴子逛了逛,然后发现了好多关于数据结构线性表,具体来说是单链表的问题.有的是没有一点思路,无从下手:有的是看不懂代码,不理解关键字以及被形参的形式气的不行,我总结了一下常见问题来给大家带来干货,到后面还有简单案例来巩固知识,弄透一题胜无脑刷百题,接下来是正文内容. 详解typedef关键字 含义 C语言允许用户使用

  • C语言深入探索递归的特点

    目录 递归的认识 main函数可以递归吗 递归核心思想讲解 递归的缺点 递归的认识 基本认识: 1.首先递归的本质还是函数调用,也要形成和释放栈帧. 2.函数的调用是有成本的,这个成本在时间和空间上表现为函数栈帧的形成和销毁. 3.递归就是 不断形成栈帧和销毁的过程. 理论认识: 1.内存和cpu中的资源有限,也就决定啦,合理的递归是绝对不可以无限递归下去的. 2.递归不是什么时候都可以使用的,而是要满足自身的场景,即目标函数的子问题可以用该算法解决,本质是分治的思想. 3.递归的核心:大事化小

  • C语言详细分析浮点数在内存中的储存

    目录 浮点数的储存格式 初步了解 深入探究 E不全为0或不全为1 E全为0 E全为1 浮点数的储存格式 初步了解 首先让我们通过一段代码来认识一下浮点型和整型的区别: int main() { int n = 9;//将整型9存储到n中 float* pFloat = (float*)&n; printf("n的值为:%d\n", n); printf("*pFloat的值为:%f\n", *pFloat); *pFloat = 9.0;//将浮点型9.0存

  • C语言全面讲解顺序表使用操作

    目录 一.顺序表的结构定义 二.顺序表的结构操作 1.初始化 2.插入操作 3.删除操作 4.扩容操作 5.释放操作 6.输出 三.示例 编程环境为 ubuntu 18.04. 顺序表需要连续一片存储空间,存储任意类型的元素,这里以存储 int 类型数据为例. 一.顺序表的结构定义 size 为容量,length 为当前已知数据表元素的个数 typedef struct Vector{ int *data; //该顺序表这片连续空间的首地址 int size, length; } Vec; 二.

  • C语言详细图解浮点型数据的存储实现

    目录 在引入知识之前,先来看一个案例,就知道了解浮点型数据存储的重要性与必要性. 举个例子: #define _CRT_SECURE_NO_WARNINGS 1 #include<stdio.h> int main() { int num = 9; float *pnum = (float *)&num;//强制转换类型 printf("n的值为:%d\n",n); printf("*pFloat的值为:%f\n",*pnum); *pnum =

随机推荐