java数据类型的转换以及精度丢失

news/2024/7/8 0:34:26

java数据类型的转换以及精度丢失_long转double会丢失精度吗_ღLiJia的博客-CSDN博客

一.浮点类型在计算机当中的存储 

在这里插入图片描述

  • float存储需求是4字节(32位), 其中1位最高位是符号位,中间8位表示阶位,后32位表示值
    • float的范围: -2^128 ~ +2^128,也即-3.40E+38 ~ +3.40E+38
    • float的精度: 2^23 = 8388608,一共七位,这意味着最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字
  • double存储需求是8字节(64为),其中1位最高位是符号位,中间11位表示阶位,后52位表示值
    • 取值范围: -2^1024 ~ +2^1024,也即-1.79E+308 ~ +1.79E+308 
    • 精度: 2^52 = 4503599627370496,一共16位,同理,double的精度为15~16位
  • long数据类型是64位有符号Java原始数据类型。
    • 取值范围: -9223372036854775808到9223372036854775807 (”-2^64“ 到”2^64 -1)

精度丢失就是我们的位数不够表示我们整个数值了

问题原因:

首先计算机进行的是二进制运算,我们输入的十进制数字会先转换成二进制,进行运算后再转换为十进制输出。Float和Double提供了快速的运算,然而问题在于转换为二进制的时候,位数不够表示我们整个数值,有些数字不能完全转换,只能无限接近于原本的值,这就导致了在后来的运算会出现不正确结果的情况。

整体转换图 

如图所示,其中:

  • 实线byte→short、short→int、int→long、int→double、char→int、float→double转换是不会发生精度丢失的,因为后者所包含的范围比前者大且完全包含前者。
  • 虚线int转float、long转float,long转double都会发生精度丢失。精度丢失包括两种,一是有效数字丢失,一是目标类型完全无法表示数据

原因如下:

int和float都是32位,但是内存结构也就是存储结构是不一样的,float只有24(含隐含的一位整数位)位来确定精度,而int是32位。long转float,long转double精度丢失原理是一样

详解:
我们知道,float的存储结构是1个符号位,8个指数位,23个尾数。

  • 符号位,表述浮点数的正或者负,0代表正,1代表负。
  • 指数位,实际也是有正负的,但是没有单独的符号位,在计算机的世界里,进位都是二进制的,指数表示的也是2的N次幂,8位指数表达的范围是0到255,而对应的实际的指数是-127到128。也就是说实际的指数等于指数位表示的数值减127。
  • 尾数位,只代表了二进制的小数点后的部分,小数点前的那位被省略了,当指数位全部为0时省略的是0否则省略的是1。

所以可以说,实际上尾数确定了浮点数的精度,而数的大小主要是靠指数位,尾数只有23位,加上隐含的一位整数位便是24位。也就是说int类型的值在2^24以内,float是可以精确表示的,但是当超过这个数的时候就不一定能精确表示了。其他类型也是如此。 

取值范围:

1、int。

  • 最小值:Integer.MIN_VALUE= -2147483648 (-2的31次方)
  • 最大值:Integer.MAX_VALUE= 2147483647  (2的31次方-1)

2、double。

  • 最小值:Double.MIN_VALUE=4.9E-324 (2的-1074次方)
  • 最大值:Double.MAX_VALUE=1.7976931348623157E308 (2的1024次方-1)
  • 负值取值范围为:  -1.7976E+308 到 -4.94065645841246544E-324,
  • 正值取值范围为: 4.94065645841246544E-324 到 1.797693E+308
    • (e+308表示乘以10的308次方,而e-324 表示乘以10的负324次方)
  • float有效数字8位,double有效数字16位

3、long。

  • 最小值:Long.MIN_VALUE=-9223372036854775808 (-2的63次方)
  • 最大值:Long.MAX_VALUE=9223372036854775807 (2的63次方-1)

4、float 。

  • 最小值:Float.MIN_VALUE=1.4E-45 (2的-149次方)
  • 最大值:Float.MAX_VALUE=3.4028235E38 (2的128次方-1)
    • ​​​​​​​​​​​​​​(e+38 表示乘以10的38次方,而e-45 表示乘以10的负45次方)
System.out.println("Long.MAX_VALUE: ---> " + Long.MAX_VALUE);
System.out.println("Double.MAX_VALUE: ---> " + new Double(Double.MAX_VALUE).longValue());
System.out.println("Double.MAX_VALUE: --->" + new Double(1.797693e+308).longValue());

// 打印结果
Long.MAX_VALUE: ---> 9223372036854775807
Double.MAX_VALUE: ---> 9223372036854775807
Double.MAX_VALUE: --->9223372036854775807

 ​​​​​​​​​​​二、 Java数据类型及转换原则

赋值和方法调用转换规则:从低位类型到高位类型自动转换,从高位类型到低位类型需要强制类型转换:

  (1)布尔型和其它基本数据类型之间不能相互转换;
  (2)byte型可以转换为short、int、、long、float和double;
  (3)short可转换为int、long、float和double;
  (4)char可转换为int、long、float和double;
  (5)int可转换为long、float和double;
  (6)long可转换为float和double;
  (7)float可转换为double;

  其中,int转换为char类型,float类型都需要强转,会导致精度丢失
   long转换为double也需要强转,会导致精度丢失

 三、打印数值

char类型的最大值:127
char类型的最小值:-128
signed char类型的最大值:127
signed char类型的最小值:-128
unsigned char类型的最大值:255

short类型的最大值:32767
short类型的最小值:-32768
unsigned short类型的最大值:65535

int类型的最大值:2147483647
int类型的最小值:-2147483648
unsigned int类型的最大值:4294967295

long类型的最大值:2147483647
long类型的最小值:-2147483648
unsigned long类型的最小值:4294967295

float类型的尾数位数:24
float类型的最小有效数字位数:6
带有全部有效数字位数的float类型的负指数的最小值:38
带有全部有效数字位数的float类型的正指数的最大值:-37
保留全部精度的float类型正数的最小值:1.175494e-038
保留全部精度的float类型正数的最大值:3.402823e+038
1.00和比1.00大的最小的float类型值之间的差值:1.192093e-007

double类型的尾数位数:53
double类型的最小有效数字位数:15
带有全部有效数字位数的double类型的负指数的最小值:308
带有全部有效数字位数的double类型的正指数的最大值:-307
保留全部精度的double类型正数的最小值:2.225074e-308
保留全部精度的double类型正数的最小值:1.797693e+308
1.00和比1.00大的最小的double类型值之间的差值:2.220446e-016

long double类型的尾数位数:64
long double类型的最小有效数字位数:18
带有全部有效数字位数的long double类型的负指数的最大值:4932
带有全部有效数字位数的long double类型的正指数的最小值:-4931
保留全部精度的long double类型正数的最小值:3.205284e-317
保留全部精度的long double类型正数的最大值:3.205284e-317
1.00和比1.00大的最小的long double类型值之间的差值:3.205284e-317


http://lihuaxi.xjx100.cn/news/1063879.html

相关文章

【JavaEE初阶】多线程(二)线程状态以及多线程安全问题

摄影分享~~ 文章目录 线程的状态多线程带来的风险线程安全线程安全的原因解决线程不安全问题(加锁)synchronized关键字-监视器锁monitor locksynchronized的特性 java中的死锁问题死锁死锁的三个典型情况死锁的四个必要条件如何避免死锁? J…

IDEA下SpringBoot指定配置文件启动项目

目录 一. idea下的SpringBoot启动:指定配置文件 二. 项目已打包,运行配置 1).使用java -jar启动基于(一)下的配置文件启动 2)指定项目内其它配置文件application-pro.yml启动项目 3) Linux服务器上启动基于(三)的…

数据库基础篇 《6. 多表查询》

目录 1. 一个案例引发的多表连接 1.1 案例说明 1.2 笛卡尔积(或交叉连接)的理解 1.3 案例分析与问题解决 2. 多表查询分类讲解 分类1:等值连接 vs 非等值连接 等值连接 非等值连接 ​编辑 分类2:自连接 vs 非自连接 分类3&…

经典数据结构之2-3树

2-3树定义 2-3树,是最简单的B-树,其中2、3主要体现在每个非叶子节点都有2个或3个子节点,B-树即是平衡树,平衡树是为了解决不平衡树查询效率问题,常见的二叉平衡书有AVL树,它虽然提高了查询效率&#xff0c…

【小样本分割 2020 ICCV】PANet

文章目录 【小样本分割 2020 ICCV】PANet1. 简介2. 网络2.1 整体架构2.2 原型学习2.3 非参数度量学习2.4 原型对齐正则化 3. 代码3.1 backbone3.2 模型代码 【小样本分割 2020 ICCV】PANet 论文题目:PANet: Few-Shot Image Semantic Segmentation with Prototype Al…

自学SQL入门(1)

SQL SQL是结构化查询语言(Structured Query Language)的缩写,是用于管理和操作关系型数据库的标准语言。它是一种声明性语言,可以用于创建、查询、更新和删除数据库中的数据。 SQL具有以下特点: SQL是一种标准语言&a…

144. 二叉树的前序遍历【78】

难度等级:容易 上一篇算法: 102. 二叉树的层序遍历【206】 力扣此题地址: 144. 二叉树的前序遍历 - 力扣(Leetcode) 1.题目:144. 二叉树的前序遍历 给你二叉树的根节点 root ,返回它节点值的 前…

小程序开发费用估算:如何控制项目成本?

在当今数字化的时代,小程序已经成为了很多企业和个人开展业务的重要手段。小程序的开发需要耗费时间和资源,因此在项目初期,了解预计的开发费用是非常重要的。本文将详细介绍如何估算小程序开发费用以及如何控制项目成本。 小程序开发费用 …