我是靠谱客的博主 阳光汉堡,这篇文章主要介绍关于Java中double精度丢失原因详情,现在分享给大家,希望可以做个参考。

先展示一下精度丢失:
在这里插入图片描述

下面是模拟精度丢失的核心代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// 定义数组长度 private static final int LEN = 64; public static void paddingString(double n, StringBuilder sb, int len) { if (len < 0) { return; } if (n > 1) { n = n - 1; paddingString(n, sb, len); } else if (n < 1) { n *= 2; } if (n > 1) { sb.append(1); paddingString(n, sb, --len); return; } else if (n < 1) { sb.append(0); paddingString(n, sb, --len); return; } else { sb.append(1); return; } } private static byte[] setBitArray(String s) { byte[] arr = new byte[LEN]; int temp; for (int i = LEN; i > 0; i--) { temp = s.charAt(i - 1) - 48; arr[i - 1] = (byte) temp; } return arr; } public static double binaryToDouble(byte[] s) { BigDecimal two = new BigDecimal(2); BigDecimal bigDecimal = new BigDecimal(0); BigDecimal temp = BigDecimal.ONE; BigDecimal temp1; for (int i = 0; i < s.length; i++) { temp = temp.divide(two); if (s[i] > 0) { int a = s[i]; temp1 = new BigDecimal(a); bigDecimal = bigDecimal.add(temp.multiply(temp1)); } } return bigDecimal.doubleValue(); } public static String doubleToBinary(double n) { StringBuilder stringBuffer = new StringBuilder(LEN); // 填充并得到二进制结果 paddingString(n, stringBuffer, LEN); int len; if ((len = stringBuffer.length()) > LEN + 1) { return stringBuffer.toString().substring(0, LEN + 1); } else { return stringBuffer.toString().substring(0, len); } } public static byte[] bytesAdd(byte[] a, byte[] b) { byte[] arr = new byte[LEN]; for (int i = LEN - 1; i > 0; i--) { arr[i] = (byte) (arr[i] + a[i] + b[i]); if (arr[i] > 1) { arr[i] -= 2; arr[i - 1] = 1; } } return arr; }

精度丢失测试案例:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public static void main(String[] args) { String s = doubleToBinary(.1); // 转成二进制字符串 byte[] bytes = setBitArray(s); // 转成二进制数组 (一) double d = binaryToDouble(bytes); // 在转double, 反向验证结果的准确性 System.out.println("十进制: " + d); System.out.println("========下面同理========="); String s1 = doubleToBinary(.2); byte[] bytes1 = setBitArray(s1); // (二) double d1 = binaryToDouble(bytes1); System.out.println("十进制: " + d1); byte[] add = bytesAdd(bytes, bytes1); // 二进制数组累加 (三) System.out.println("result: " + binaryToDouble(add)); // 将数组转换为小数 }

在这里插入图片描述

我们可以看到,已经成功模拟出来了,精度丢失。现在我可以明确的给出精度丢失的原因:存放double数字的数组,是有限位的(符号位1,指数位11,尾数部分52,float是1,8,23),所以在数字的小数位转二进制时,如果转换后的二进制是个死循环,那么就会把后面的尾数抛弃掉(从这里发生的精度丢失,位于测试代码的 (一)、(二)部分),造成转10进制时,出现了精度丢失!

另外关于如果解决精度丢失问题,用java.math包下的BigDecimal类。
下期,我可能会讲解:如何自己解决精度丢失问题。拭目以待吧~


如果你有什么问题,就请提出来吧,我看到了就会解答~ 同时我也谢谢大家大家的评论、点赞。





作者留言:大家一起进步,冲啊!



最后

以上就是阳光汉堡最近收集整理的关于关于Java中double精度丢失原因详情的全部内容,更多相关关于Java中double精度丢失原因详情内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(63)

评论列表共有 0 条评论

立即
投稿
返回
顶部