博客
关于我
揭秘浮点数
阅读量:700 次
发布时间:2019-03-17

本文共 2404 字,大约阅读时间需要 8 分钟。

浮点数基础知识

引言

以下是关于浮点数的一些基本问题和解答。这些问题涵盖了浮点数的表示、运算以及一些特殊情况。希望通过这些内容,你能更好地理解浮点数的工作原理。

1. 关于浮点数的基本问题

问题1:double d = 1.25d; float f = 1.25f; System.out.println((a - b) == 0.0); 请问输出结果是什么?

这个问题涉及到浮点数的精度问题。在Java中,doublefloat 是不同的数据类型,double 有更高的精度(大约是52位有效数字)而 float 只有单精度(大约是32位有效数字)。由于浮点数在转换过程中可能会丢失精度,因此即使两个数看起来相等,它们的二进制表示可能并不完全相同。因此,a - b 的结果可能不等于0.0。

问题2:double c = 0.2; double d = 0.3; double e = 0.4; 请问 c - dd - e 是否相等?

这个问题涉及到浮点数的精度问题。由于浮点数无法精确表示所有的十进制小数,其表示方式是二进制的,因此0.2、0.3和0.4的浮点数值可能不完全等于它们的十进制表示。在这种情况下,c - dd - e 的结果可能都不等于0.0。

问题3:System.out.println(1.0 / 0.0); 的结果是什么?

当我们将0除以0时,会发生除以零的错误。在Java中,这会抛出一个ArithmeticException(算术异常)。

问题4:System.out.println(0.0 / 0.0); 的结果是什么?

同样地,当我们将0除以0时,会抛出一个ArithmeticException(算术异常)。与问题3的情况类似,这是因为没有定义0除以0的结果。

问题5:public void g(double i) { } public void g(float d) { } public void g(long l) { } public void g(short l) { } public void g(Double dd) { } g(1); 请问会调用哪个方法?

这个问题涉及到方法的选择规则。在Java中,方法的选择是基于参数的严格类型匹配。g(1) 中的参数1是一个整数类型,而所有方法的参数都是浮点数或整数类型。由于整数类型不会被视为浮点数,因此会选择具有最接近的参数类型的方法。在这种情况下,g(1) 会调用g(long l) 方法,因为整数1会被推断为long 类型。

2. 浮点数的基本概念

机器数

机器数是指计算机中使用的二进制表示形式。它是数值在计算机中的实际二进制表示。

真值

真值是机器数所代表的实际数值。例如,二进制数1001 的真值是9。

原码

原码是机器数最高位表示符号位,其余各位表示二进制数的绝对值。例如,原码表示正数和负数的方式。

补码

补码是原码的变形方式。对于一个正数,补码与原码相同;对于一个负数,补码等于2^n + 原码,其中n是机器数的位数。

移码

移码是用来表示浮点数的阶码的。它只能表示整数,表示将一个数向左或右偏移若干单位。

3. 定点数与浮点数

定点数和浮点数的主要区别在于它们的表示范围。定点数的数值范围较小,而浮点数的范围较大。尽管浮点数能够表示更大的范围,但其精度较低。

溢出

溢出是指运算结果超出了数的表示范围。浮点数的溢出判断通常采用单符号位溢出判别法。

单符号位溢出判别法

单符号位溢出判别法的规则如下:

  • s1s2 = 00:结果为正数,无溢出。
  • s1s2 = 01:结果为正数,发生正溢出。
  • s1s2 = 11:结果为负数,无溢出。
  • s1s2 = 10:结果为负数,发生负溢出。

4. IEEE 754 标准

IEEE 754标准规定了浮点数的表示格式。任意一个二进制浮点数真值N可以表示为: [ (-1)^s \times 1.M \times 2^E ] 其中:

  • s 是符号位,0表示正数,1表示负数。
  • 1.M 是有效数字,M是尾数。
  • 2^E 是指数位。

IEEE 754浮点数格式

IEEE 754标准规定了三种常用的浮点数格式:短浮点数(单精度float)、长浮点数(双精度double)和临时浮点数(无隐含位)。

IEEE 754浮点数的规格化

为了提高运算的精度,浮点数通常采用规格化形式。规格化操作包括左规和右规。

左规

左规是将尾数左移一位,阶码减1(r=2时)。这通常用于非规格化浮点数的规格化。

右规

右规是将尾数右移一位,阶码加1(r=2时)。这通常用于浮点数运算结果的尾数溢出。

5. 浮点数的计算

浮点数的计算分为阶码运算和尾数运算两个步骤。阶码运算的目的是使两个数的阶码相等,然后进行尾数运算。

对阶

对阶是通过调整阶码使两个数的阶码相等。阶码小的数需要向右移,阶码大的数需要向左移。

尾数运算

尾数运算包括加法、减法、乘法和除法。这些运算需要考虑溢出和舍入。

溢出与舍入

浮点数的溢出与舍入通常由尾数的最高位是否为有效值来决定。规格化浮点数的尾数最高位必须是一个有效值。

6. 浮点数的误差

浮点数的误差主要来源于其二进制表示方式。由于二进制小数无法精确表示所有的十进制小数,因此在转换过程中可能会丢失精度。

二进制小数的精度问题

二进制小数的精度问题导致浮点数在表示某些十进制小数时会出现误差。例如,0.1在二进制浮点数中无法精确表示。

7. 类型转换

在Java中,类型转换需要注意以下几点:

  • 从窄范围到宽范围的转换不会丢失精度。
  • 从宽范围到窄范围的转换需要显式声明。

结语

通过本文的内容,我们可以看到浮点数在计算机中的重要性。浮点数的表示、运算和特殊值对程序的性能和准确性有着直接影响。理解浮点数的工作原理对于编写高性能的程序至关重要。

转载地址:http://yqpez.baihongyu.com/

你可能感兴趣的文章
mabatis 中出现< 以及> 代表什么意思?
查看>>
Mac book pro打开docker出现The data couldn’t be read because it is missing
查看>>
MAC M1大数据0-1成神篇-25 hadoop高可用搭建
查看>>
mac mysql 进程_Mac平台下启动MySQL到完全终止MySQL----终端八步走
查看>>
Mac OS 12.0.1 如何安装柯美287打印机驱动,刷卡打印
查看>>
MangoDB4.0版本的安装与配置
查看>>
Manjaro 24.1 “Xahea” 发布!具有 KDE Plasma 6.1.5、GNOME 46 和最新的内核增强功能
查看>>
mapping文件目录生成修改
查看>>
MapReduce程序依赖的jar包
查看>>
mariadb multi-source replication(mariadb多主复制)
查看>>
MariaDB的简单使用
查看>>
MaterialForm对tab页进行隐藏
查看>>
Member var and Static var.
查看>>
memcached高速缓存学习笔记001---memcached介绍和安装以及基本使用
查看>>
memcached高速缓存学习笔记003---利用JAVA程序操作memcached crud操作
查看>>
Memcached:Node.js 高性能缓存解决方案
查看>>
memcache、redis原理对比
查看>>
memset初始化高维数组为-1/0
查看>>
Metasploit CGI网关接口渗透测试实战
查看>>
Metasploit Web服务器渗透测试实战
查看>>