1 概述

Java 是一门面向对象的编程语言,其核心原则之一是一切皆对象。然而,基本数据类型(如 int、double、char 等)并非对象,不具备对象的特性,例如不能调用方法、不能参与继承体系等。而包装类(如 Integer、Double、Character 等)作为 Object 的子类,将基本数据类型进行了对象化封装,使得它们能够更好地融入到 Java 面向对象的编程环境中,符合面向对象的设计理念。如下图所示,内置类和对应的包装类:

内置类型(基本数据类型)对应的包装类(java.lang 包下)说明
byteByte8 位整数,用于表示范围相对较小的整数值,取值范围是 -128 到 127(包含边界值)。
shortShort16 位整数,可表示的数值范围比 byte 更大一些,范围是 -32768 到 32767(包含边界值)。
intInteger32 位整数,在日常编程中使用频率较高,能表示较广泛的整数值,范围是 -2147483648 到 2147483647(包含边界值)。
longLong64 位整数,适用于需要表示更大范围整数的场景,例如处理大文件的字节数、时间戳等,其取值范围极大。
floatFloat32 位浮点数,用于表示单精度的小数,在存储和运算时会存在一定的精度损失,常用于对精度要求不是特别高的浮点数值表示场景。
doubleDouble64 位浮点数,双精度浮点数,相比 float 能提供更高的精度,常用于科学计算、金融计算等对精度要求相对较高的领域,但同样存在精度问题。
charCharacter字符类型,用于表示单个字符,在 Java 中采用 Unicode 编码,可以表示世界上几乎所有的字符,例如字母、数字、标点符号以及各种语言的字符等。
booleanBoolean布尔类型,只有两个取值,即 true(真)和 false(假),常用于条件判断、逻辑控制等场景,比如在 if 语句、while 语句等控制结构中使用。

包装类中通用的方法:

方法分类方法定义(以Xxx代表具体包装类,T代表对应基本类型)说明适用所有包装类
拆箱(基本类型转换)T xxxValue()将包装类对象转换为对应的基本类型(如Integer.intValue()Character.charValue()
装箱(对象创建)static Xxx valueOf(T value)将基本类型转换为包装类对象(可能使用缓存,提高效率)
字符串解析为基本类型static T parseXxx(String s)将字符串解析为对应基本类型(如Integer.parseInt("123")Boolean.parseBoolean("true")Character
字符串解析(带进制)static T parseXxx(String s, int radix)按指定进制(2-36)解析字符串(仅整数型包装类支持,如Integer.parseInt("1010", 2)整数型(Integer/Long/Byte/Short
字符串转换static String toString(T value)将基本类型转换为字符串(如Integer.toString(123)Boolean.toString(true)
对象转字符串String toString()重写ObjecttoString(),返回包装类对象的字符串表示
数值比较static int compare(T a, T b)比较两个基本类型的值,返回-1(a<b)、0(a==b)、1(a>b)
常量:最大值static final T MAX_VALUE表示对应基本类型的最大值(如Integer.MAX_VALUEByte.MAX_VALUEBoolean
常量:最小值static final T MIN_VALUE表示对应基本类型的最小值(如Long.MIN_VALUEFloat.MIN_VALUEBoolean
常量:位数static final int SIZE表示对应基本类型的二进制位数(如Integer.SIZE=32Double.SIZE=64Boolean

对于Character 类型表示的Unicode 编码范围(0到65535),是字符编码的边界值。

2 不同数据类型的取值范围与使用场景

包装类对应基本类型占用内存(位)数值范围精度特性典型场景
Bytebyte8−27-2^727 ~ 27−12^7 - 1271(即 -128 ~ 127)整数,无精度损失存储小范围整数(如文件字节、ASCII 字符),节省内存。
Shortshort16−215-2^{15}215 ~ 215−12^{15} - 12151(即 -32768 ~ 32767)整数,无精度损失存储中等范围整数(如短数组、小范围计数),比 int 更省内存。
Integerint32−231-2^{31}231 ~ 231−12^{31} - 12311(即 -2147483648 ~ 2147483647)整数,无精度损失日常编程中最常用的整数类型(如循环计数、数组索引、普通数值计算)。
Longlong64−263-2^{63}263 ~ 263−12^{63} - 12631整数,无精度损失存储大范围整数(如时间戳、文件大小、大数值计数),避免溢出。
Floatfloat32±3.4×1038\pm 3.4 \times 10^{38}±3.4×1038(单精度,有效位数约 6-7 位)浮点数,可能有精度损失对精度要求不高的场景(如图形处理、科学计算中的近似值),内存占用比 double 小。
Doubledouble64±1.7×10308\pm 1.7 \times 10^{308}±1.7×10308(双精度,有效位数约 15-17 位)浮点数,精度高于 float,但仍可能有损失对精度要求较高的场景(如金融计算、科学实验数据),是默认浮点类型(如 1.2 默认为 double)。

3 浮点型存储方式

Java 中浮点型(floatdouble)遵循 IEEE 754 标准 进行存储,采用科学计数法的二进制形式表示,核心思想是用“符号位 + 指数位 + 尾数位”三部分存储数值,以平衡精度和表示范围。

float(32位单精度)的存储结构

32位总长度划分为三部分:

位区域位数作用
符号位(S)1位0表示正数,1表示负数(仅表示符号,不影响数值大小)。
指数位(E)8位存储指数的“偏移值”,用于表示数值的数量级(范围:-126 ~ +127)。
尾数位(M)23位存储二进制小数的有效数字(默认隐含一位整数“1”,实际精度为24位)。

示例:存储 0.5f

转换方式为乘二取整法,在IEE754中要求,第一位得为1,所以会将小数点右移并乘10的n次方达到上述目的,次数n位指数,小数部分为位数。

  • 二进制为 1.0 × 2⁻¹
  • 符号位 S=0(正数)
  • 指数 E = -1 + 127(偏移量)= 126 → 二进制 01111110
  • 尾数位 M = 0(因 1.0 的小数部分为0)
  • 最终32位存储:0 01111110 00000000000000000000000

double(64位双精度)的存储结构

64位总长度划分为三部分:

位区域位数作用
符号位(S)1位float,0为正,1为负。
指数位(E)11位存储指数的“偏移值”,表示范围更大(-1022 ~ +1023)。
尾数位(M)52位存储二进制小数的有效数字(默认隐含一位整数“1”,实际精度为53位)。

示例:存储 0.5(默认double

  • 二进制为 1.0 × 2⁻¹
  • 符号位 S=0
  • 指数 E = -1 + 1023(偏移量)= 1022 → 二进制 01111111110
  • 尾数位 M = 0
  • 最终64位存储:0 01111111110 00000000000000000000000000000000000000000000000000000000

floatdouble 的核心区别

类型总位数符号位指数位尾数位指数范围(二进制)指数范围(十进制)有效精度(二进制)有效精度(十进制)适用场景
float32位1位8位23位-126 ~ +127±3.4×10³⁸24位(含隐含位)6-7位精度要求低、内存敏感场景
double64位1位11位52位-1022 ~ +1023±1.7×10³⁰⁸53位(含隐含位)15-17位高精度计算(如金融、科学计算)

4 精确度问题

有些小数不能精确的转成小数,例如0.1:
以下是将十进制小数 0.1 转换为二进制小数的详细计算步骤,按照乘2取整的方法逐步推导( 乘 2 取整法):

实例

步骤一:初始化

我们要将十进制小数 0.1 转换为二进制,先记录下当前待转换的十进制小数为 0.1

步骤二:第一次乘2取整

将当前的十进制小数乘以 2,即:

此时,取乘积结果的整数部分作为二进制小数小数点后的第一位数字,这里整数部分是 0,所以二进制小数目前为 0.0

然后记录下此次乘积结果的小数部分 0.2,用于后续继续计算。

步骤三:第二次乘2取整

用上一步得到的小数部分 0.2 乘以 2,可得:

取这个乘积结果的整数部分作为二进制小数小数点后的第二位数字,整数部分为 0,此时二进制小数变为 0.00
同样,记录下此次乘积结果的小数部分 0.4 用于下一步计算。

步骤四:第三次乘2取整

用新得到的小数部分 0.4 乘以 2

取整数部分作为二进制小数小数点后的第三位数字,这里整数部分是 0,二进制小数更新为 0.000
接着记录下小数部分 0.8 继续下一步操作。

步骤五:第四次乘2取整

用小数部分 0.8 乘以 2

取整数部分 1 作为二进制小数小数点后的第四位数字,此时二进制小数变为 0.0001
记录下此次乘积结果的小数部分 0.6,用于后续计算。

步骤六:第五次乘2取整

0.6 乘以 2

取整数部分 1 作为二进制小数小数点后的第五位数字,二进制小数更新为 0.00011
再记录下小数部分 0.2,继续下一步运算。

步骤七:第六次乘2取整

用新出现的小数部分 0.2 乘以 2

取整数部分 0 作为二进制小数小数点后的第六位数字,二进制小数变为 0.000110
记录下小数部分 0.4,准备下一轮计算。

步骤八:后续循环

可以发现,从这一步开始,后续出现的小数部分 0.4 又回到了之前步骤三出现过的情况,后续的计算将会不断重复出现 0.40.81.61.2 等这些小数部分以及对应的取整结果,陷入循环。

所以,十进制小数 0.1 转换为二进制小数的结果是 0.00011001100110011...,这是一个无限循环的二进制小数,通常可以表示为 0.0\dot{0}110(在二进制下循环节为 0110)。

如果按照IEEE 754标准将其存储为 floatdouble 类型时,由于尾数位长度有限(float 的尾数位23位,double 的尾数位52位),只能截取前面有限的位数来近似表示这个无限循环的二进制小数,从而导致了精度损失。例如在 float 类型中存储时,实际存储的是这个无限循环二进制小数的近似值,并非精确的 0.1 在二进制下的完整表示。

Double的尾数有52位,而Float仅仅有23位,因此double具有更高的精度。

5 BigInteger和BigDecimal

在 Java 中,BigInteger和BigDecimal是两个用于高精度数值计算的类(你可能想说的是BigDecimal,Java 中并没有BigDouble这个类哦),它们解决了基本数据类型(如int、double等)在处理大数值以及高精度要求场景下的精度不足等问题。

BigInteger

BigInteger 是 Java 中用于表示任意精度整数的类,其存储方式与基本整数类型(如 int、long)有本质区别,核心是通过动态数组存储二进制原码的各位,从而支持任意大小的整数。BigInteger 内部通过一个 int[] 数组(名为 mag,即 “magnitude” 的缩写)存储整数的绝对值的二进制补码表示,并使用一个 int 类型的 signum 标记符号:signum:符号位,取值为 1(正数)、0(零)、-1(负数)。

实例

12345678901234567890(约10¹⁹)为例,来直观理解 BigIntegermag 数组的存储方式:

步骤1:计算整数的绝对值和二进制表示

  • 整数为正数,signum = 1(符号为正)。
  • 绝对值就是 12345678901234567890
  • 转换为二进制(简化表示,实际很长):
    10101101011110011100110111100111011011101011101011010110100010010

步骤2:按32位拆分二进制位(大端序)

mag 数组的每个元素是32位 int,按高位在前、低位在后的大端序存储,且不保留前导零:

  1. 将二进制从左到右(高位到低位)每32位分一组:

    • 第一组(最高位32位):1010110101111001110011011110011
    • 第二组(次高位32位):1011011101011101011010110100010
    • 第三组(剩余低位,不足32位补0,但因无需求前导零,实际存储有效位):0010(此处仅为示例,实际会补齐32位但去除前导零)。
  2. 每组转换为十进制 int 值,存入 mag 数组:

    • 第一组对应 int 值:2874452659
    • 第二组对应 int 值:2995155810
    • 第三组对应 int 值:2(简化后)。
  3. 最终 mag 数组为:[2874452659, 2995155810, 2]

BigDecimal

BigDecimal 主要是为了解决浮点数(如 float、double)在运算时因二进制存储格式而产生精度损失的问题。在很多对精度要求严苛的领域,比如金融行业(涉及货币金额计算、利息计算、汇率换算等)、科学计算中需要精确数值的情况等,都需要使用 BigDecimal 来确保计算结果的准确性。

BigDecimal 采用 “整数数组 + 小数点位置 + 符号位” 的三元存储结构,彻底解决了浮点型(float/double)的精度损失问题,以下是其存储方式的详细解析:

核心存储结构

BigDecimal 内部通过三个关键部分表示一个十进制数:

  1. BigInteger intVal:存储数值的"无小数点整数形式"(所有有效数字,不含小数点)。
  2. int scale:表示小数点位置(即小数部分的位数,scale ≥ 0 时为小数位数,scale < 0 时表示整数部分后有 -scale 个零)。
  3. 符号位:由 intVal 内部的 signum 变量表示(1 为正,-1 为负,0 为零)。

存储细节拆解

123.45-67.890 为例,具体说明存储逻辑:

例1:存储 123.45(正数)
  • 步骤1:处理数值为无小数点整数
    去掉小数点,保留所有有效数字 → 12345
    这部分由 intValBigInteger 类型)存储,其内部 mag 数组为 [12345](二进制拆分的整数绝对值)。

  • 步骤2:记录小数点位置(scale
    原数小数点后有 2 位 → scale = 2

  • 步骤3:标记符号
    正数 → signum = 1

    最终存储:intVal=12345 + scale=2 + signum=1 → 还原为 12345 / 10² = 123.45

例2:存储 -67.890(负数)
  • 步骤1:处理数值为无小数点整数
    去掉小数点和负号 → 67890(注意:末尾的 0 是有效数字,会保留)。
    intValmag 数组为 [67890]

  • 步骤2:记录小数点位置(scale
    原数小数点后有 3 位 → scale = 3

  • 步骤3:标记符号
    负数 → signum = -1

    最终存储:intVal=67890 + scale=3 + signum=-1 → 还原为 -67890 / 10³ = -67.890

特殊场景处理

  1. 整数(如 123)
    scale = 0(无小数部分),存储为 intVal=123 + scale=0123 / 10⁰ = 123

  2. 纯小数(如 0.0045)
    无小数点整数为 45scale = 445 / 10⁴ = 0.0045

  3. 科学计数法(如 1.23e+5 = 123000)
    等价于 123000scale = -2scale < 0 表示整数部分后补 2 个零) → 123 × 10² = 123000

总结

BigDecimal 通过 “剥离小数点保留全部有效数字(intVal)+ 记录小数点位置(scale)+ 单独标记符号” 的设计,实现了十进制数的完全精确存储。这种方式避开了二进制与十进制转换的天然矛盾,是高精度场景(如货币计算)的必备工具。

其核心思想可概括为:“用整数存储所有有效数字,用 scale 记住小数点在哪,用 signum 标记正负”

有效数字的存储和BigInteger 一致也就是,BigDecimal可以表示任意精度的数字。

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

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

相关文章

【系统分析师】高分论文:论信息系统开发方法及应用

【摘要】 本文以某国有企业的 B2B 商品棉交易平台的电子商务门户网站系统&#xff08;以下简称“门户网站”&#xff09;建设为例&#xff0c;讨论信息系统开发方法及应用。本文作者认为项目实施中选择合适的开发方法&#xff0c;既能满足用户需求&#xff0c;又能提高整个项目…

开源 C++ QT Widget 开发(七)线程--多线程及通讯

文章的目的为了记录使用C 进行QT Widget 开发学习的经历。临时学习&#xff0c;完成app的开发。开发流程和要点有些记忆模糊&#xff0c;赶紧记录&#xff0c;防止忘记。 相关链接&#xff1a; 开源 C QT Widget 开发&#xff08;一&#xff09;工程文件结构-CSDN博客 开源 C…

CPU-IO-网络-内核参数的调优

CPU-IO-网络-内核参数的调优CPU-IO-网络-内核参数的调优一、CPU 资源调优1.1 调整进程优先级&#xff08;nice 值&#xff09;1.2 设置 CPU 亲和力&#xff08;taskset&#xff09;1.3 cpu命令描述1.4 使用 vmstat 分析系统瓶颈二、磁盘 I/O 调优2.1 ulimit 资源限制2.2 测试磁…

JavaScript 实战进阶:工程化、性能与未来展望

一、JavaScript 工程化实践 随着前端项目规模的扩大&#xff0c;“工程化”成为提升开发效率、保证代码质量的核心手段。它涵盖模块化设计、构建工具链、代码规范与测试等多个维度。 &#xff08;一&#xff09;模块化开发 模块化是将复杂代码拆分为可复用、可维护的独立单元的…

破局与增长:全球电商的业财一体化战略与数字化未来

一、全球电商的数字化转型背景在瞬息万变的全球电商市场中&#xff0c;数字化转型已经成为企业保持竞争力的必由之路。近年来&#xff0c;国内品牌出海企业快速扩张&#xff0c;业务范围覆盖数十个国家和平台。然而&#xff0c;随着规模的几何级增长&#xff0c;行业普遍面临以…

Excel怎么换行?3种单元格内换行方法?【图文详解】Excel自动换行?Alt+Enter?

一、问题背景 在日常使用 Excel 处理数据时&#xff0c;很多人会遇到这样的困扰&#xff1a;输入长文本&#xff08;比如产品说明、多行备注、地址信息等&#xff09;时&#xff0c;文字会一直横向延伸&#xff0c;不仅导致单元格变宽、表格排版混乱&#xff0c;还可能遮挡相邻…

【生产实践】局域网多服务器多用户SSH登录批量测试(附完整shell脚本)

在企业运维场景中&#xff0c;局域网内多台服务器的SSH登录凭据&#xff08;用户名/密码&#xff09;验证是高频需求——无论是新服务器部署后的凭据校验&#xff0c;还是定期安全巡检中的凭据有效性检查&#xff0c;手动逐台逐用户测试不仅效率低下&#xff0c;还容易出错。 本…

专题:2025人工智能2.0智能体驱动ERP、生成式AI经济现状落地报告|附400+份报告PDF、原数据表汇总下载

原文链接&#xff1a;https://tecdat.cn/?p43713 2025年&#xff0c;人工智能正从技术概念快速渗透到产业实操层面——大模型推理能力的突破让复杂任务自动化成为可能&#xff0c;AI代理的规模化应用重构企业效率边界&#xff0c;而AI企业“天生全球化”的特性更是打破了传统创…

机器学习--支持向量机

目录 一、为什么需要 SVM&#xff1f;先解决 “怎么分才好” 的问题 二、SVM 的核心&#xff1a;什么是 “最好的超平面”&#xff1f;用 “间隔” 说话 1. 先搞懂两个关键概念 2. 目标&#xff1a;把 “间隔” 拉到最大 三、从 “想要最大间隔” 到 “解数学问题”&#…

Multi-output Classification and Multi-label Classification|多输出分类和多标签分类

----------------------------------------------------------------------------------------------- 这是我在我的网站中截取的文章&#xff0c;有更多的文章欢迎来访问我自己的博客网站rn.berlinlian.cn&#xff0c;这里还有很多有关计算机的知识&#xff0c;欢迎进行留言或…

【目标检测】论文阅读5

Small-object detection based on YOLOv5 in autonomous driving systems 发表期刊&#xff1a;Pattern Recognition Letters&#xff1b;发表时间&#xff1a;2023年 论文地址 摘要 随着自动驾驶领域的快速发展&#xff0c;对更快、更准确的目标检测框架的需求已经成为必要。…

Playwright进阶指南 (6) | 自动化测试实战

2025企业级测试解决方案&#xff1a;从单测到千级并发&#xff0c;打造高可用测试体系一、为什么传统自动化测试难以落地&#xff1f;根据2025年最新行业调研&#xff0c;测试项目失败的三大核心原因&#xff1a;失败原因占比典型表现维护成本过高45%选择器频繁失效&#xff0c…

uv 简单使用

二进制安装 powershell -ExecutionPolicy Bypass -c "irm https://ghproxy.cn/https://github.com/astral-sh/uv/releases/download/0.8.13/uv-installer.ps1 | iex"版本号&#xff1a;0.8.13&#xff0c;自行更改github加速前缀&#xff1a;https://ghproxy.cn/ 配置…

Linux程序管理

目录 一、Linux程序与进程 1、程序,进程,线程的概念 2、程序和进程的区别 3、进程和线程的区别 二、Linux进程基础(生命周期) 1、进程生命周期 2、父子进程的关系 三、程序管理 1、课程目标 2、常见的软件包类型 3、安装方法 使用独立的rpm包安装 rpm包的命名方法…

Linux-进程替换exec

文章目录进程替换exec 函数族使用说明查看命令的路径 which测试 execl测试 execlp测试 execv测试 execvp进程替换 概述 在 Windows 平台下&#xff0c;我们可以通过双击运行可执行程序&#xff0c;让这个可执行程序成为一个进程&#xff1b;而在 Linux 平台&#xff0c;我们可…

Seaborn数据可视化实战:Seaborn数据可视化实战入门

Seaborn数据可视化实战&#xff1a;从数据到图表的完整旅程 学习目标 通过本课程的学习&#xff0c;你将能够掌握使用Seaborn进行数据可视化的完整流程&#xff0c;从数据准备到图表设计&#xff0c;再到最终的图表呈现。本课程将通过一个具体的项目案例&#xff0c;帮助你全面…

控制系统仿真之时域分析(二)

一、时域分析法时域分析法是从传递函数出发直接在时域上研究控制系统性能的方法&#xff0c;实质上是研究系统在某典型输入信号下随时间变化的曲线&#xff0c;从而分析系统性能。控制系统的时域响应决定于系统本身的参数和结构&#xff0c;还有系统的初始状态&#xff0c;以及…

PDF 表单创建与分发

PDF 表单是一种交互式文档&#xff0c;允许用户填写信息、做出选择并提交数据。与静态 PDF 不同&#xff0c;PDF 表单包含可交互的字段元素&#xff0c;如文本框、复选框、单选按钮等。#mermaid-svg-sZe9We4UG0yKymyl {font-family:"trebuchet ms",verdana,arial,san…

Guava 简介:让 Java 开发更高效

Guava 简介&#xff1a;让 Java 开发更高效 Guava 是由 Google 开源的 Java 库&#xff0c;旨在为开发者提供一系列实用的工具类&#xff0c;以提高开发效率。它包含了集合类、缓存、并发工具、字符串处理等实用方法。 Guava 的常用场景 集合处理&#xff1a;Guava 提供了多种扩…

「ECG信号处理——(24)基于ECG和EEG信号的多模态融合疲劳分析」2025年8月23日

目录 一、引言 二、核心原理 2.1 心电 HRV 疲劳关联原理 2.2 脑电 EEG 疲劳关联原理 2.3 疲劳综合指数 三、数据处理流程 四、结果展示与分析 参考文献 一、引言 针对作业安全&#xff08;如驾驶、精密操作&#xff09;场景下的疲劳状态实时监测需求&#xff0c;本文提…