由于对float或double 的使用不当,可能会出现精度丢失的问题。问题大概情况可以通过如下代码理解
public class FloatDoubleTest {
public static void main(String[] args) {
float f = 20014999;
double d = f;
double d2 = 20014999;
System.out.println("f=" + f);
System.out.println("d=" + d);
System.out.println("d2=" + d2);
}
}
得到的结果如下:
f=2.0015E7
d=2.0015E7
d2=2.0014999E7
|
|
从输出结果可以看出double
可以正确的表示20014999
,而float
没有办法表示20014999
,得到的只是一个近似值。这样的结果很让人讶异。20014999
这么小的数字在float下没办法表示。于是带着这个问题,做了一次关于float和double学习,做个简单分享,希望有助于大家对java
浮点数的理解。
关于
java
的
float
和
double
Java
语言支持两种基本的浮点类型: float
和 double
。java
的浮点类型都依据 IEEE 754
标准。IEEE 754
定义了32
位和 64
位双精度两种浮点二进制小数标准。
IEEE 754
用科学记数法以底数为 2
的小数来表示浮点数。32
位浮点数用 1
位表示数字的符号,用 8
位来表示指数,用 23
位来表示尾数,即小数部分。作为有符号整数的指数可以有正负之分。小数部分用二进制(底数 2
)小数来表示。对于64
位双精度浮点数,用 1
位表示数字的符号,用 11
位表示指数,52
位表示尾数。如下两个图来表示:
float(32位):
double(64位):
都是分为三个部分:
(1)
一个单独的符号位s
直接编码符号s
。
(2)k
位的幂指数E
,移码表示
。
(3)n
位的小数,原码表示
。
那么 20014999
为什么用
float
没有办法正确表示?
结合float和double的表示方法,通过分析
20014999
的二进制表示就可以知道答案了。
以下程序可以得出
20014999
在
double
和
float
下的二进制表示方式。
输出结果如下:
Double:100000101110011000101100111100101110000000000000000000000000000
Float:1001011100110001011001111001100
对于输出结果分析如下。对于
double
的二进制左边补上符号位
0
刚好可以得到
64
位的二进制数。根据double的表示法,分为符号数、幂指数和尾数三个部分如下:
0
10000010111
0011000101100111100101110000000000000000000000000000
对于
float
左边补上符号位
0
刚好可以得到
32
位的二进制数。
根据float的表示法,
也分为
符号数、幂指数和尾数三个部分如下
:
0
10010111
00110001011001111001100
绿色部分是符号位,红色部分是幂指数,蓝色部分是尾数。
对比可以得出:符号位都是
0
,幂指数为移码表示,两者刚好也相等。唯一不同的是尾数。
在
double
的尾数为:
001100010110011110010111
0000000000000000000000000000
,省略后面的零,至少需要24位才能正确表示
。
而在
float
下面尾数为:
00110001011001111001100
,共
23
位。
为什么会这样?原因很明显,因为
float尾数
最多只能表示
23
位,所以
24
位的
001100010110011110010111
在
float
下面经过四舍五入变成了
23
位的
00110001011001111001100
。所以
20014999
在
float
下面变成了
20015000
。
也就是说
20014999
虽然是在float的表示范围之内,但
在
IEEE 754
的
float
表示法精度长度没有办法表示出
20014999
,而只能通过四舍五入得到一个近似值。
总结:
浮点运算很少是精确的,只要是超过精度能表示的范围就会产生误差。往往产生误差不是因为数的大小,而是因为数的精度。因此,产生的结果接近但不等于想要的结果。尤其在使用
float
和
double
作精确运算的时候要特别小心。
可以考虑采用一些替代方案来实现。如通过
String
结合
BigDecimal
或者通过使用
long
类型来转换。
分享到:
相关推荐
浮点类型的精度在<float.h>头文件中有规定,例如,float通常有6位有效数字,double有15位,这影响了数值转换时的精度保持。 理解这些基础知识对于编写高效且可靠的C语言程序至关重要。在编程实践中,需要合理利用...
- **浮点型转换**:float可以自动转换为double,而double转换为float、float转换为int或long,或者任何整型转换为float或double都需要强制转换。浮点转换可能丢失精度,因为浮点数是近似表示的。 4. **类型转换...
浮点数家族包含三种主要类型:float、double和long double。它们在内存中占用的字节数分别为4字节、8字节和8字节(对于long double,其大小可能因平台而异,但通常为8字节)。 float类型的精度相对较低,可以表示...
这里是对应java基础及面试题(1.0)的重要面试题 ...long到float不用强转,因为float表示的范围确实比long表示的范围大,虽然它只占4个字节,而long占8个字节,float是用科学记数法来表示数据的,long是用二进
- **实型变量**:通过关键字`float`或`double`来定义,其中`double`类型的精度更高,占用更多内存空间。例如: - `float f = 1.23;` - `double d = 1.23456789;` - **字符型类型及其表示**: - **字符常量**:...
1. **基本类型之间的转换**:Java中有八种基本数据类型,包括整型(byte, short, int, long)、浮点型(float, double)、字符型(char)以及布尔型(boolean)。它们之间可以进行隐式或显式转换。例如,较小的数值...
- `Double` 至少可以存储 15 位数字的精度。 2. **`Float`**: - `Float` 用于存储 32 位浮点数。 - 当对精度要求不高时,可以选择使用 `Float`。 - `Float` 至少可以存储 6 位数字的精度。 #### 四、布尔类型...
值类型包括整型(如int, byte, short等)、浮点型(如float, double)、无符号类型(如uint, ulong)以及枚举类型(enum)和结构(struct)。这些类型存储的是实际的数据,当赋值或传递时,会复制整个数据的副本。 ...
A) int B) float C) double D) 不确定 **解析**: - 整型、浮点型和双精度型数据进行运算时,结果类型为参与运算的最大类型,即双精度型。 **答案**: C) double 15. **题目**: 在 C 语言中,char 型数据在...
3. **避免隐式转换导致的错误**:当类型转换可能引起意料之外的行为时,如可能导致精度损失或溢出,可以使用强制转换明确指定预期行为。 ### 指针类型转换 (Pointer Type Conversion) 在C语言中,指针类型转换允许...
- Java中的浮点型数据类型包括float和double,其中double具有更高的精度。 4. ASP.NET数据库访问: - 使用ASP.NET访问Sql Server数据库时,需要导入的命名空间是System.Data.SqlClient。 5. SQL索引创建: - ...
`float` 是单精度浮点类型,而 `double` 是双精度类型,提供更高的精度。 #### 题目8: 计算机病毒特征 - **知识点**: - 传染性: 病毒能够自我复制并传播到其他系统。 - 潜伏性: 病毒可能隐藏在系统中一段时间而不...
13. Java的浮点型数据分为float和double,double具有更高的精度。 14. 被删除的文件在回收站未清空前可以恢复,但一旦清空回收站,文件通常无法找回。 15. ASP.NET访问SqlServer数据库需要导入`System.Data....
浮点型如FLOAT和DOUBLE用于表示小数,但可能存在精度问题。DECIMAL或NUMERIC则能精确表示小数,适合处理货币等需要精确数值的场景。字符串类型包括VARCHAR、TEXT、MEDIUMTEXT和BLOB,用于存储文本和二进制数据。日期...
- 浮点型:`float`(单精度浮点数,32位),`double`(双精度浮点数,64位)。浮点数用于处理小数部分的数值,通常在科学计算中使用。 - 字符型:`char`,用于存储单个字符,如字母、数字或其他符号,它占16位。 - ...
- **解释**:由于浮点数的精度限制,直接使用float或double进行金融级的计算可能会产生误差。 - **实践建议**:对于需要高精度的计算场景,推荐使用BigDecimal类进行处理。 ### 总结 遵循以上军规不仅有助于提高...
23. Java中数值类型的转换,从小到大依次为byte→short→int→long→float→double。 24. 图表可以与数据放在不同的工作表中,Excel允许这种分离。 25. 由于题目缺失,无法提供程序段运行结果。 这些知识点涉及到...
16. Java语言的浮点型数据分为float和double,double具有更高的精度。 17. 给定的C程序计算结果是B.2,1。程序中a=d/10%9的结果为2,b=a&&( -1)的结果为1。 18. 在程序开发中,导入其他包的类通常使用import关键字...
- **float**:长度为4个字节(32位),使用IEEE 754单精度浮点格式,取值范围大约是-3.4 * 10^38到3.4 * 10^38,精确到约6-7位小数。 - **double**:长度为8个字节(64位),同样遵循IEEE 754双精度浮点格式,取值...
7. Java浮点型:Java中的浮点型数据包括float和double,其中double具有更高的精度。 8. Windows快捷键:Ctrl+C是Windows中的复制快捷键,与菜单中的复制功能相同,所以正确答案是正确。 9. PowerPoint自定义动画:...