当前位置: 首页 > news >正文

整数和浮点数转换时的精度损失

文章目录

  • int和float转换时的精度损失
    • float组成解析
      • (1) 32位浮点数的结构
      • (2)示例:解析一个浮点数
      • (3)偏置值的作用
      • (4) 偏置值为什么是127?
      • (5)对比双精度浮点数(double)
    • 精度损失
      • (1)float→ int 的精度损失
        • 原因:
      • (2)int → float 的精度损失
  • 同理的long和double
    • (1)long
    • (2)double

实线代表无信息丢失转换,虚线代表可能有精度损失的转换。
在这里插入图片描述

int和float转换时的精度损失

在这里插入图片描述

float组成解析

(1) 32位浮点数的结构

单精度浮点数(float)占用 32位(4字节),按以下方式划分:

组成部分位数作用描述
符号位(Sign)1 bit决定数值的正负:0表示正数,1表示负数。
阶码(Exponent)8 bit存储指数部分(需减去偏置值 127 得到实际指数)。
尾数(Mantissa)23 bit存储小数部分(隐含开头的 1.,实际精度为24位)。

(2)示例:解析一个浮点数

假设32位二进制为:
0 10000010 01100000000000000000000

  • 符号位0 → 正数。
  • 阶码10000010(二进制) = 130(十进制) → 实际指数 = 130 - 127 = 3
  • 尾数01100000000000000000000 → 隐含“1.”后为 1.011(二进制) = 1 + 0.25 + 0.125 = 1.375(十进制)。
  • 最终值:+1.375×23=11.0+1.375×23=11.0。

(3)偏置值的作用

  • 支持负指数
    • 若实际指数为 -3,则存储为 -3 + 127 = 124(二进制 01111100)。
    • 若实际指数为 5,则存储为 5 + 127 = 132(二进制 10000100)。
  • 统一比较规则
    阶码作为无符号数时,直接比较大小即可判断指数的大小关系(无需处理符号位)。

(4) 偏置值为什么是127?

  • 对于 8位阶码,可能的值范围是 0 ~ 255
  • 标准规定:
    • 阶码范围 1 ~ 254:表示规格化数(实际指数 -126 ~ +127)。
      (因为 1 - 127 = -126254 - 127 = +127)。这里包括0,且这里是指数0和下面的阶码0不一样。
    • 阶码 0:表示非规格化数(Denormalized Numbers)或零。
    • 阶码 255:表示无穷大(Infinity)或非数值(NaN)。
  • 因此,偏置值 127对称中心,使指数范围均衡覆盖正负值。

(5)对比双精度浮点数(double)

类型总位数符号位阶码位数尾数位数偏置值
float321823127
double64111521023

双精度(double)提供更高的精度和更大的范围,但占用两倍内存。

精度损失

(1)float→ int 的精度损失

原因:
  • 小数部分截断float 可能包含小数,而 int 是纯整数,转换时小数部分直接被丢弃(不是四舍五入)。

    float f = 3.14f;
    int i = (int)f; // i = 3(丢失 0.14)
    
  • 超出 int 范围float 的表示范围(约 ±3.4×10³⁸)远大于 int(−2³¹ 到 2³¹−1),大数值转换会溢出。

    float f = 1e20f;
    int i = (int)f; // i = Integer.MAX_VALUE(溢出)
    

(2)int → float 的精度损失

尾数位数限制float 只有 23 位有效尾数(实际精度约 6-7 位十进制数),若 int 的绝对值超过 223=8,388,608223=8,388,608,低位数字会被舍入。

int i = 16_777_717;     // 二进制:1_00000000_00000000_00010101
float f = (float)i;      // f = 16_777_720.0(最后3位被舍入)

同理的long和double

(1)long

  • 存储格式:纯二进制补码形式,直接存储整数值。

  • 组成

    部分位数说明
    符号位1 bit0 表示正数,1 表示负数。
    数值位63 bit存储整数的绝对值,采用补码编码(负数取反加1)。

(2)double

  • 存储格式:科学计数法的二进制形式,分为符号、阶码、尾数三部分。

  • 组成

    部分位数说明
    符号位(S)1 bit0 正数,1 负数。
    阶码(E)11 bit存储指数(实际指数 = E - 1023,偏置值1023)。
    尾数(M)52 bit存储小数部分(隐含前导 1.,实际尾数为 1.M)。
http://www.xdnf.cn/news/428167.html

相关文章:

  • 拓扑排序(竞赛)
  • 按键精灵ios脚本新增元素功能助力辅助工具开发(二)
  • 春秋云镜 Time Writeup
  • 面试中被问到谈谈你对threadlocal的理解
  • 2025年5月-信息系统项目管理师高级-软考高项一般计算题
  • 基于Session实现短信登录全流程详解
  • 数据治理的核心
  • 论文知识总结
  • 日常知识点之随手问题整理(vcpkg安装osgearth并进行测试简单整理)
  • 【Ubuntu】扩充磁盘大小
  • 求1+3+5+7+9+…,其和小于等于500 的最大项
  • Java线程池性能优化全解析:从配置到实践
  • Redis学习笔记
  • SAP Business One(B1)打开自定义对象报错【Failed to initialize document numbering:】
  • 大模型核心运行机制
  • 玩转ChatGPT:DeepSeek实战(统一所在地格式)
  • 基于STM32、HAL库的TDA7719TR音频接口芯片驱动程序设计
  • RK3568移植鸿蒙系统openharmony-5.1.0-release
  • 【愚公系列】《Manus极简入门》036-物联网系统架构师:“万物互联师”
  • 数据结构基础--蓝桥杯备考
  • 在Flutter上如何实现按钮的拖拽效果
  • Ceph 集群常用管理命令
  • esp32硬件支持AT指令
  • 什么类型的网站适合用WAF?Web应用防火墙的适用场景解析
  • Python(1) 做一个随机数的游戏
  • MySQL索引底层数据结构与算法
  • Vue 2 和 Vue 3的比较(二、语法差异)
  • Excel的详细使用指南
  • Mac修改hosts文件方法
  • Linux文件编程——标准库函数fopen、fread、fwrite等函数