iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >float 和 double (我内存里的浮点型数据?)
  • 609
分享到

float 和 double (我内存里的浮点型数据?)

2023-06-03 09:06:20 609人浏览 泡泡鱼
摘要

二更,因为好几个人因为这篇文章把我批斗了,把有问题的地方修正。今天看到一个问题能不能用double去取代float?前段时间,有个朋友问我,在java里面我想把一个高精度的浮点型存储下来,但是每次存储的时候都会被强制降低精度,对于浮点型的理

二更,因为好几个人因为这篇文章把我批斗了,把有问题的地方修正。

今天看到一个问题

能不能用double去取代float?

前段时间,有个朋友问我,在java里面我想把一个高精度的浮点型存储下来,但是每次存储的时候都会被强制降低精度,对于浮点型的理解,真的非常非常重要,特别对嵌入式软件开发,或者算法开发,涉及到数据类的,浮点型非常非常关键,就比如,微信为什么不让我发0.0000000001 元的微信红包呢? 有没有想过这个问题?如果这样做对于他们服务器后台的运算能力要求非常高,so,~~~~~

所以想简单写一下,float和double的区别以及应用场景

<img src="https://pic3.zhimg.com/v2-19c15ba72548ffb535861e5a5625b65a_b.jpg" data-caption="" data-size="nORMal" data-rawwidth="281" data-rawheight="25" class="content_image" width="281">

float 和 double (我内存里的浮点型数据?)

1、浮点型的值范围

float和double的范围是由指数的位数来决定的。在Vc++6.0中,float占4个字节,double占8个字节。

Type Storage size Value range 

float 4 byte 1.2E-38 to 3.4E+38

double 8 byte 2.3E-308 to 1.7E+308

long double 10 byte 3.4E-4932 to 1.1E+4932

2、浮点型在内存里面是如何存储的?

我相信这个问题大家没有好好的去考虑过,浮点型如何存储,这才是我们讨论浮点型的关键所在,关于上面的浮点型取值范围,也是网上拷贝下来的,至于真实性,我觉得你们要看了这部分才可能真正理解浮点型,而且最好在自己的编译器去测试,浮点型是可以等于负数的,所以上面的范围,你们认为是正确的吗?

<img src="Https://pic2.zhimg.com/v2-9d554740d41074c27e49febf5448c86d_b.jpg" data-caption="" data-size="normal" data-rawwidth="300" data-rawheight="300" class="content_image" width="300">

float 和 double (我内存里的浮点型数据?)

我拿float来举个栗子:

<img src="https://pic4.zhimg.com/v2-8a912b5c1343b1223ea36b94538dd67f_b.jpg" data-size="normal" data-rawwidth="637" data-rawheight="191" class="origin_image zh-lightbox-thumb" width="637" data-original="https://pic4.zhimg.com/v2-8a912b5c1343b1223ea36b94538dd67f_r.jpg">

float 和 double (我内存里的浮点型数据?)

float在内存中的存储方式

以下 部分如发现问题,请留言,会发小小红包感谢,微信weiqifa0

首先使用基数2而不是基数10来表示科学计数法变体中的浮点值。例如,值3.14159可以表示为

570795 * 2^{1}

570795是有效数字又名尾数(在上图中指尾数部分); 它是包含有效数字的数字的一部分。此值乘以基数2,上升到1的幂,得到3.14159。

浮点数通过存储有效数和指数(以及符号位)进行编码。

典型的32位布局如下所示:

 3 32222222 22211111111110000000000

 1 09876543 21098765432109876543210

+-+--------+-----------------------+

| |        |                       |

+-+--------+-----------------------+

 ^    ^                ^

 |    |                |

 |    |                +-- 有效数 

 |    |

 |    +------------------- 指数

 |

 +------------------------ 符号位

与有符号整数类型一样,高位表示符号; 表示值,1表示值。

而对于指数部分,因为指数可正可负,8位的指数位能表示的指数范围就应该为:-127-128了, 所以指数部分的存储采用移位存储,存储的数据为元数据+127

举例:

<img src="https://pic1.zhimg.com/v2-0df447013f853a47b89d51dd0d88a288_b.jpg" data-caption="" data-size="normal" data-rawwidth="191" data-rawheight="98" class="content_image" width="191">

float 和 double (我内存里的浮点型数据?)

剩余的比特用于有效数字。每个位表示从左侧算起的2的负幂,float一共23,举例:

<img src="https://pic2.zhimg.com/v2-f5a935ed3397d4b35c3592e0059f492d_b.jpg" data-caption="" data-size="normal" data-rawwidth="625" data-rawheight="81" class="origin_image zh-lightbox-thumb" width="625" data-original="https://pic2.zhimg.com/v2-f5a935ed3397d4b35c3592e0059f492d_r.jpg">

float 和 double (我内存里的浮点型数据?)

某些平台假定有效数中的“隐藏”前导位始终设置为1,因此有效数中的值始终在[0.5,1之间]。这允许这些平台以稍高的精度存储值。

所以3.14159的值将表示为

    0 10000000 10010010000111111010000

    ^ ^        ^

    | |        |

    | |        + ---有效数= 1.570795 ...

    | |

    | + -------------------指数= 2(130  -  128)

    |

    + ------------------------- sign = 0(正面)

    value = 1 (符号位) * 2 (指数位) *(有效数字)

    值= 1 0 * 2^1 * 1.570795 ...

    值= 3.14159 ......

现在,如果你将有效数字中的所有位相加,你会注意到它们总共不是3.14195;

他们实际上3.141590118408203125,(小编实测数据)

没有足够的位来准确存储值; 我们只能存储一个近似值。有效数字中的位数决定了精度23位给出了大约6位精度的十进制数字。64位浮点类型在有效位数中提供足够的位,可提供大约1215位的精度。但要注意,有一些数值不能被精确表示。就像1/3这样的值不能用有限数量的十进制数字表示,由于值是近似值,因此使用它们进行计算也是近似值,并且累积误差会累积。

<img src="https://pic2.zhimg.com/v2-9d554740d41074c27e49febf5448c86d_b.jpg" data-caption="" data-size="normal" data-rawwidth="300" data-rawheight="300" class="content_image" width="300">

float 和 double (我内存里的浮点型数据?)

#include<stdio.h>

void main(void)

{

    for(float i = ; i < 1;i+= 0.01)

    {

        printf("%f \r\n",i);

    }

    for(double i = ; i < 1;i+= 0.01)

    {

        printf("%f\r\n",i);

    }

    for(long double i = ; i < 1;i+= 0.01)

    {

        printf("%Lf\r\n",i);

    }

}

注意其中输出

<img src="https://pic2.zhimg.com/v2-6a46dbbc43ef82e569ea483166516b61_b.jpg" data-size="normal" data-rawwidth="161" data-rawheight="238" class="content_image" width="161">

float 和 double (我内存里的浮点型数据?)

到0.830000之后明显出现了误差

<img src="https://pic3.zhimg.com/v2-19c15ba72548ffb535861e5a5625b65a_b.jpg" data-caption="" data-size="normal" data-rawwidth="281" data-rawheight="25" class="content_image" width="281">

float 和 double (我内存里的浮点型数据?)

3、反向验证第二点的存储推断

上面的计算,我们可以通过一个小代码反向验证,代码如下

#include<stdio.h>

int main()

{

   

    float num = 3.14159f;

    int *p = (int *)&num;

    printf("0x%x\n", *p);

    return ;

}

<img src="https://pic3.zhimg.com/v2-74b26980679454ee8f3862b9fa9813D6_b.jpg" data-size="normal" data-rawwidth="617" data-rawheight="40" class="origin_image zh-lightbox-thumb" width="617" data-original="https://pic3.zhimg.com/v2-74b26980679454ee8f3862b9fa9813d6_r.jpg">

float 和 double (我内存里的浮点型数据?)

输出16进制数据

so~~~~

14159 0x40490fd0 = 0 10000000 10010010000111111010000

<img src="https://pic4.zhimg.com/v2-4bda4f506f20dbb3baa4096af2d960a7_b.jpg" data-size="normal" data-rawwidth="573" data-rawheight="230" class="origin_image zh-lightbox-thumb" width="573" data-original="https://pic4.zhimg.com/v2-4bda4f506f20dbb3baa4096af2d960a7_r.jpg">

float 和 double (我内存里的浮点型数据?)

16进制对应二进制数据

对于double 和 long double的大小和精度可以通过这个方式来验证。

<img src="https://pic3.zhimg.com/v2-19c15ba72548ffb535861e5a5625b65a_b.jpg" data-caption="" data-size="normal" data-rawwidth="281" data-rawheight="25" class="content_image" width="281">

float 和 double (我内存里的浮点型数据?)

4、浮点型printf输出格式

printf输出范围 %f %g %Lf %e

#include<stdio.h>

void main(void)

{

    float f_sum = ;

    double d_test = ;

    

    f_sum = -3.4*10e-38;

    d_test = -1.7*10e-308;

    printf("%.38f\r\n",f_sum);

    printf("%.308f\r\n",d_test);

    printf("%g\r\n",f_sum);

    printf("%g\r\n",d_test);

    

    f_sum = 3.4*10e37;

    d_test = 1.7*10e307;

    printf("%g\r\n",f_sum);

    printf("%g\r\n",d_test);

}

输出如下

weiqifa@ubuntu:~/c/float$ GCc float.c && a.out

-0.00000000000000000000000000000000000034

-0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017

-3.4e-37

-1.7e-307

4e+38

7e+308

weiqifa@ubuntu:~/c/float$

<img src="https://pic3.zhimg.com/v2-19c15ba72548ffb535861e5a5625b65a_b.jpg" data-caption="" data-size="normal" data-rawwidth="281" data-rawheight="25" class="content_image" width="281">

float 和 double (我内存里的浮点型数据?)

5 精度问题

浮点数在内存中是按科学计数法来存储的,其整数部分始终是一个隐含着的"1",由于它是不变的,故不能对精度造成影响。

float:2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字;

double:2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位。

<img src="https://pic2.zhimg.com/v2-9d554740d41074c27e49febf5448c86d_b.jpg" data-caption="" data-size="normal" data-rawwidth="300" data-rawheight="300" class="content_image" width="300">

float 和 double (我内存里的浮点型数据?)

小代码举例

#include "stdio.h"

int main(void)

    float fa = 1.0f; 

    float fb = -2.123456789f; 

    float fc = 3.999999f; 

    double da = 1.0; 

    double db = -4.0000000; 

    double dc = 3.123456789012345; 

    printf("%-32.32f \r\n%-32.32f \r\n%-32.32f\r\n",fa,fb,fc);

    printf("%-64.64f \r\n%-64.64f \r\n%-64.64f\r\n",da,db,dc);

    return

输出

00000000000000000000000000000000 

-2.12345671653747558593750000000000 

99999904632568359375000000000000

0000000000000000000000000000000000000000000000000000000000000000 

-4.0000000000000000000000000000000000000000000000000000000000000000 

1234567890123448030692543397890403866767883300781250000000000000

<img src="https://pic3.zhimg.com/v2-19c15ba72548ffb535861e5a5625b65a_b.jpg" data-caption="" data-size="normal" data-rawwidth="281" data-rawheight="25" class="content_image" width="281">

float 和 double (我内存里的浮点型数据?)

6、浮点值和 “0”

不知道大家对精度是怎么看的,理论上浮点是永远不可能等于“0”的,只能无尽接近于 “0”,所以你拿浮点型 和“0” 比较 ,千万千万不要用 “== ”恒等于符号,而是用大小于符号,精度越大,说明越无尽接近于 “0”,有时候float的精度容易引起问题,看下面的例子。---之前写的,下面论证是否正确

评论已经有人说,浮点值肯定可以等于1,这个不再做论证,现在论证浮点值和值,是不是相等的。

所以,我做了实验,我的文章不一定保证正确,但是提出的观点一定要有论证的根据

晚上回来很累,跟楠哥睡了一下,10点的时候,楠哥又起来了,我也想更新下评论的问题,我测试的代码如下,里面有注释。

#include "stdio.h"

int main()

{

       

//int it = 0b01000000010010010000111111010000;

int it = 0b00111111100000000000000000000000;

        float *num = (float*)&it;

float num1;

int *p = (int *)&num1;

printf("%f\r\n",*num);

printf("%f\r\n",num1);

printf("0x%x\r\n",*p);

int it2 = 0x401980;

float *num3 = (float *)&it2;

printf("%f\r\n",*num3);

printf("%-32.32f\r\n",*num3);

printf("%d\r\n",(int)*num3);

    return 0;

}

输出如下图

<img src="https://pic1.zhimg.com/v2-92a07e5e1560c1cca7236f150b099918_b.jpg" data-caption="" data-size="normal" data-rawwidth="552" data-rawheight="168" class="origin_image zh-lightbox-thumb" width="552" data-original="https://pic1.zhimg.com/v2-92a07e5e1560c1cca7236f150b099918_r.jpg">

float 和 double (我内存里的浮点型数据?)

<img src="https://pic3.zhimg.com/v2-19c15ba72548ffb535861e5a5625b65a_b.jpg" data-caption="" data-size="normal" data-rawwidth="281" data-rawheight="25" class="content_image" width="281">

float 和 double (我内存里的浮点型数据?)

7、总结

1、浮点型在内存里面的存储方式

2、浮点型的精度问题

3、浮点型的

--结束END--

本文标题: float 和 double (我内存里的浮点型数据?)

本文链接: https://www.lsjlt.com/news/233945.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • float 和 double (我内存里的浮点型数据?)
    二更,因为好几个人因为这篇文章把我批斗了,把有问题的地方修正。今天看到一个问题能不能用double去取代float?前段时间,有个朋友问我,在java里面我想把一个高精度的浮点型存储下来,但是每次存储的时候都会被强制降低精度,对于浮点型的理...
    99+
    2023-06-03
  • 关于MYSQL中FLOAT和DOUBLE类型的存储
    关于MYSQL中FLOAT和DOUBLE类型的存储 其实在单精度和双精度浮点类型存储中其存储方式和C/C++一致准守IEEE标准他们都是浮点型的,所谓的浮点型,是小数点的位置可变,其能够表示的范围比定点...
    99+
    2024-04-02
  • C语言浮点型数据在内存中的存储方式是什么
    本篇内容介绍了“C语言浮点型数据在内存中的存储方式是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、思考一下咱们先上一盘开胃菜,试试看...
    99+
    2023-07-05
  • C语言数据(整数、浮点数)在内存中的存储
    本篇主要讨论:整数、浮点数在内存中是怎么保存的! 数据类型详细介绍 在前面C语言基础概览中,已经提到过了基本的C语言内置类型,但C语言的数据类型有无数种~ 但是可以把这些类型分为几个...
    99+
    2024-04-02
  • C语言数据的存储超详细讲解下篇浮点型在内存中的存取
    目录前言浮点型在内存中的存储浮点数存储的例子浮点数存储规则IEEE 754规定IEEE 754对有效数字M的特别规定IEEE 754对指数E的特别规定存入内存是E的规定从内存取出时E...
    99+
    2024-04-02
  • C语言中字符型数据和浮点型数据介绍
    目录字符型1.来练练,输出一个字符A2.将小写字母转为大写字母浮点型先来看看float代码以下是双精度的浮点型double练习题新的一天又开始了哈,又是好好学习的一天啦。话不多说,直...
    99+
    2024-04-02
  • C++浮点数在内存中的存储详解
    目录前言:浮点数的表示形式浮点数存储模型有效数字M指数E例题讲解总结前言: 我们在码代码的时候,经常遇到过以整数形式存入,浮点数形式输出;或者浮点数形式存入整数形式输出。输出的结果往...
    99+
    2024-04-02
  • C语言中字符型数据和浮点型数据怎么用
    本篇内容主要讲解“C语言中字符型数据和浮点型数据怎么用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C语言中字符型数据和浮点型数据怎么用”吧!字符型首先要了解ASII码,这里面有很多东东,但只要...
    99+
    2023-06-26
  • C语言中的浮点数据类型
    目录1. 处理带小数的数值2. 浮点类型 3. 浮点类型的sizeof1. 处理带小数的数值 我们来讨论一下类似于1.234567,0.00001,这类非整数的数据。我们先试试看,i...
    99+
    2024-04-02
  • C语言详细图解浮点型数据的存储实现
    目录在引入知识之前,先来看一个案例,就知道了解浮点型数据存储的重要性与必要性。 举个例子: #define _CRT_SECURE_NO_WARNINGS 1 #include<...
    99+
    2024-04-02
  • Redis缓存数据库的数据类型和优点
    这篇文章主要讲解了“Redis缓存数据库的数据类型和优点”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis缓存数据库的数据类型和优点”吧!已经有了Me...
    99+
    2024-04-02
  • C++中整形与浮点型如何在内存中的存储详解
    目录1 数据类型1.1 类型的基本归类2 整形在内存中的存储2.1 二进制的三种形式2.2 大小端字的介绍3 浮点数在内存中的存储3.1 浮点数存储规则1 数据类型 前面我们已经知道...
    99+
    2024-04-02
  • C语言详细分析浮点数在内存中的储存
    目录浮点数的储存格式初步了解深入探究E不全为0或不全为1E全为0E全为1浮点数的储存格式 初步了解 首先让我们通过一段代码来认识一下浮点型和整型的区别: int main() { ...
    99+
    2024-04-02
  • PHP 变量和数据类型的内存使用
    PHP 使用动态内存分配系统来管理变量和数据类型。 这意味着在运行时根据需要分配和释放内存。 创建变量时,PHP 会分配一块内存来存储变量的值。 基本数据类型 PHP 支持多种基本数据类型,每...
    99+
    2024-02-27
  • redis是什么类型的内存数据库
    redis 是一种基于内存的开源数据库,使用键值存储模型,具有极高的读写速度。其特性包括:内存存储:数据存储在内存中,而不是磁盘上。键值存储:数据以键值对形式存储,其中键是唯一标识符,值...
    99+
    2024-04-08
  • 浅谈Java中浮点型数据保留两位小数的四种方法
    目录一、String类的方式二、DecimalFormat类三、BigDecimal类进行数据处理四、NumberFormat类进行数据处理总结一下今天在进行开发的过程中遇到了一个小...
    99+
    2024-04-02
  • SessionStorage:数据存储的能力和支持的数据类型
    探索 SessionStorage 的功能:它可以存储什么类型的数据? SessionStorage 是 HTML5 中提供的一种客户端存储方式,可以用来在客户端存储数据,且只在当前会话期间有效。与 Cookie 类似,但 Se...
    99+
    2024-01-15
    数据存储
  • ABAP Netweaver和Hybris里获得内存使用统计数据
    ABAP Netweaver 事物码ST06 ...
    99+
    2024-04-02
  • 文件处理和数据类型:ASP面试的难点在哪里?
    在ASP(Active Server Pages)面试中,文件处理和数据类型通常被认为是比较困难的问题,因为它们需要深入了解ASP的工作原理和相关的技术知识。在本文中,我们将讨论这些难点,并提供一些演示代码来帮助您更好地理解这些概念。 文件...
    99+
    2023-08-30
    面试 文件 数据类型
  • 怎么购买阿里云的数据库内存
    一、引言 在云计算时代,数据库是企业信息化建设的重要组成部分,它不仅承载了企业的核心业务数据,而且也对企业的业务稳定性和安全性有着至关重要的影响。而阿里云作为国内领先的云计算服务提供商,其数据库产品丰富多样,能满足不同企业的需求。其中,数据...
    99+
    2024-01-25
    阿里 内存 数据库
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作