成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

在Java中 0.1 + 0.2 不等于0.3 ?

開發 前端
今天這篇文章跟大家一起聊聊,浮點數的精度問題,希望對你會有所幫助。

前言

在Java中浮點數的精度問題,是一個讓人非常頭疼的問題。

在文章開頭,大家一起先看看下面這個非常經典錯誤案例:

double total = 0.1 + 0.2;
System.out.println(total); // 0.30000000000000004
System.out.println(total == 0.3); // false!

計算兩個double類型的數字,0.1+0.2不等于0.3,其結果卻是:0.30000000000000004。

浮點數精度是Java數學計算的隱形炸彈

今天這篇文章跟大家一起聊聊,浮點數的精度問題,希望對你會有所幫助。

1.計算機的"數學缺陷"

1.1 IEEE 754標準的本質

浮點數內存結構

圖片圖片

64位的浮點數是由:

  • 1位符號位
  • 11位指數位
  • 52位尾數位

組成的。

0.1的二進制真相

猜猜0.1轉換成二進制的結果是什么?

System.out.println(Long.toBinaryString(Double.doubleToLongBits(0.1)));

輸出結果:11111110111001100110011001100110011001100110011001100110011010

浮點數的內部是由很多個0和1組成的。

無限循環小數

1.2 精度丟失的數學原理

誤差產生公式

Java驗證代碼

System.out.println(0.1 + 0.2);

打印結果:0.30000000000000004

System.out.println(0.1 * 0.2);

打印結果:0.020000000000000004

2.精度問題的重災區

2.1 金融計算的致命誤差

錯誤案例

電商訂單金額計算:

double price = 19.99;
double quantity = 3;
double total = price * quantity;

total的結果是:59.970000000000006

銀行利息計算:

double rate = 0.05;
double interest = 10000 * rate / 365;

每日利息誤差的結果是:1.36986301369863

如果每一個用戶的資金都有誤差,誤差日積月累,總的誤差值會很大。

2.2 科學計算的精度災難

典型場景

地理坐標計算:

double lat1 = 39.90923;
double lng1 = 116.397428;
double distance = calculateDistance(lat1, lng1, lat2, lng2);

誤差可達米級。

工業控制系統:

double sensorValue = 0.000001;
double adjusted = sensorValue * 1000000;

放大后誤差顯著。

既然這么多業務場景,都不允許出現浮點數精度問題。

那么,我們該如何解決精度問題呢?

3 解決方案

3.1 BigDecimal的正確使用

我們都知道BigDecimal能夠解決浮點數的精度問題。

但如果用錯了,也會出現問題。

錯誤用法:

BigDecimal d1 = new BigDecimal(0.1);

這里使用了使用double構造創建BigDecimal對象,會導致精度丟失。

正確用法:

BigDecimal d2 = new BigDecimal("0.1");
BigDecimal d3 = new BigDecimal("0.2");

// 精確計算
BigDecimal sum = d2.add(d3); // 0.3

使用字符串構造,會發現精度計算正確。

四則運算規范

除法必須指定精度和舍入模式:

BigDecimal result = a.divide(b, 10, RoundingMode.HALF_UP);

3.2 整數運算的藝術

貨幣計算最佳實踐

以分為單位存儲金額:

long priceInCents = 1999; // 19.99元
long quantity = 3;
long totalCents = priceInCents * quantity; // 5997分 = 59.97元

3.3 精度容忍比較

浮點數等值判斷

錯誤方式:

if (a == b) { ... }

直接使用等于號判斷兩個浮點數的大小是否相等。

正確方式:

final double EPSILON = 1e-10;
if (Math.abs(a - b) < EPSILON) { ... }

使用Math.abs函數判斷,兩個浮點數的誤差是否在可接受的范圍內。

工業級比較工具

import org.apache.commons.math3.util.Precision;

Precision.equals(0.1 + 0.2, 0.3, 1e-15); // true

4.避坑指南

浮點數使用決策樹

圖片圖片

精度保障檢查清單

  • 禁止使用float/double表示貨幣
  • BigDecimal必須用String構造
  • 除法操作指定RoundingMode
  • 浮點數比較使用誤差范圍
  • 復雜運算前進行精度測試

三條黃金法則

  1. 構造嚴謹:BigDecimal必須字符串初始化
  2. 單位轉換:金額以最小單位存儲
  3. 誤差可控:科學計算明確精度范圍
責任編輯:武曉燕 來源: 蘇三說技術
相關推薦

2023-11-08 13:32:00

JavaScript浮點數計算

2019-10-21 11:20:12

編程小程序開發

2024-08-23 08:43:08

2020-10-12 13:27:21

計算機瀏覽器電腦

2012-02-03 14:39:12

Java

2015-08-12 10:04:24

2021-09-06 15:29:16

大數據防疫信息安全

2010-04-28 14:38:26

云計算

2017-06-29 08:45:06

MySQLNOT INNOT EXISTS

2010-10-18 10:51:00

蘋果

2010-07-19 11:12:43

Perl 不等于

2023-05-16 17:42:04

浮點加法Python

2011-08-08 09:59:35

Android

2023-03-07 07:45:28

2023-06-02 13:53:56

2015-12-01 10:42:07

2022-11-02 07:39:53

CPU計算機C 語言

2013-11-26 09:55:12

2012-11-12 14:27:56

2012-11-14 09:54:14

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 97视频免费 | 一级高清视频 | 小草久久久久久久久爱六 | 日韩中文字幕一区 | 久久九精品 | 特黄特色大片免费视频观看 | 成人在线观看免费 | 欧美日韩网站 | 7777久久 | 免费一区二区三区 | 中文精品视频 | 男人的天堂在线视频 | aa级毛片毛片免费观看久 | 精品免费国产一区二区三区四区 | 国产成人免费在线 | 九九热在线精品视频 | 国产成人精品一区二区三区视频 | 不卡视频在线 | 日本高清aⅴ毛片免费 | 欧美韩一区二区 | 99热播精品| 日韩视频在线一区 | 国产精品入口麻豆www | 国产亚洲一区二区三区 | 欧美精品一区二区三区在线播放 | 午夜一级大片 | 国产特黄一级 | 久久精品国产精品青草 | 伊人网站在线观看 | 免费成人高清在线视频 | 91精品国产综合久久久动漫日韩 | 国产成人福利 | 在线成人av | 久久黄网| 亚洲日韩中文字幕一区 | 欧美久久不卡 | 国产乱码精品一区二区三区中文 | 久久九九99 | 亚洲人成网站777色婷婷 | 亚洲一区视频在线 | 国产片网站|