java精度,java精度丟失問題

本文目錄一覽:

java 浮點數為什麼精度會丟失

並不是java的浮點數精度會丟失,而是所有用二進位存儲中的浮點數都可能會精度丟失(部分特殊的小數數值可以精確表示),所以計算機中存儲的浮點數都存在精度丟失的風險,不過一邊這個丟失的精度對我們正常的使用不會構成影響。

小數在轉換為二進位時並不一定能用一個精確的二進位表示,大多數時候都是取的一個近似值,這就造成了精度的丟失。如果再用這個二進位進行計算,明顯計算結果的精度會進一步丟失。

舉個簡單的例子把0.1用二進位表示(小數與二進位轉換方法)

(1) 0.1 x 2 = 0.2  取整數位 0 得 0.0

(2) 0.2 x 2 = 0.4  取整數位 0 得 0.00

(3) 0.4 x 2 = 0.8  取整數位 0 得 0.000

(4) 0.8 x 2 = 1.6  取整數位 1 得 0.0001

(5) 0.6 x 2 = 0.2  取整數位 1 得 0.00011

(6) 0.2 x 2 = 0.4  取整數位 0 得 0.000110

(7) 0.4 x 2 = 0.8  取整數位 0 得 0.0001100

(8) 0.8 x 2 = 1.6  取整數位 1 得 0.00011001

(9) 0.6 x 2 = 1.2  取整數位 1 得 0.000110011

(n) …

得到一個無限循環的二進位小數 0.000110011…,沒辦法用一個精確的二進位表示0.1。而且計算機中存儲一個浮點數所用的位數也是有限的,所以只能選擇在某一個精度進行保存。

當然也有特殊的小數,比如0.25的二進位為0.01

附:代碼之謎(五)- 浮點數(誰偷了你的精度?)

關於java單精度與雙精度的問題

單精度和雙精度的區別就是,雙精度要比單精度所存儲的位數要多,至於說3.14師雙精度,是因為Java中,默認的小數都是double類型,也就算雙精度的,如果要定義單精度的話,那就要在小數的後面加上一個f或者F,即 double d = 3.14; float f = 3.14f; 一定要注意後面有沒有「f」和「F」啊,這個初學的時候,經常會考到。樓上說的,是對,但是,他那樣寫,就一定會報錯。記住,單精度的變數定義,一定要在值的後面加上標識。

Java語言中的浮點型數據的float和double的單精度和雙精度到底是啥意思?

主要有下面幾個區別,手冊上的,希望能幫到你

1、變數類型不同

float屬於單精度型浮點數據。

double屬於雙精度型浮點數據。

2、指數範圍不同

float的指數範圍為-127~128。

double而double的指數範圍為-1023~1024

3、表達式指數位不同

float的表達式為1bit(符號位)+8bits(指數位)+23bits(尾數位)

double的表達式為1bit(符號位)+ 11bits(指數位)+ 52bits(尾數位)

4、佔用內存空間不同

float佔4個位元組(32位)內存空間,其數值範圍為3.4E-38~3.4E+38。

double佔8 個位元組(64位)內存空間,其數值範圍為1.7E-308~1.7E+308。

5、有效位數不同

float只能提供七位有效數字。

double可提供16位有效數字。

怎麼控制精度在java

JAVA中如何對double或者float的浮點數進行精度計算,在JAVA中提供了多種參數來實現精度的不同控制方式。具體例子如下: 

轉自

Java代碼 

/* 

 * Created on 2005-6-5 

 * Author stephen 

 * Email zhoujianqiang AT gmail DOT com 

 * CopyRight(C)2005-2008 , All rights reserved. 

 */  

package com.soft4j.utility;  

  

import java.math.BigDecimal;  

  

/** 

 * 與小數位精度(四捨五入等)相關的一些常用工具方法. 

 *  

 * float/double的精度取值方式分為以下幾種: br 

 * java.math.BigDecimal.ROUND_UP br 

 * java.math.BigDecimal.ROUND_DOWN br 

 * java.math.BigDecimal.ROUND_CEILING br 

 * java.math.BigDecimal.ROUND_FLOOR br 

 * java.math.BigDecimal.ROUND_HALF_UPbr 

 * java.math.BigDecimal.ROUND_HALF_DOWN br 

 * java.math.BigDecimal.ROUND_HALF_EVEN br 

 *  

 * @author stephen 

 * @version 1.0.0 

 */  

public final class RoundTool {  

  

    /** 

     * 對double數據進行取精度. 

     * p 

     * For example: br 

     * double value = 100.345678; br 

     * double ret = round(value,4,BigDecimal.ROUND_HALF_UP); br 

     * ret為100.3457 br 

     *  

     * @param value 

     *            double數據. 

     * @param scale 

     *            精度位數(保留的小數位數). 

     * @param roundingMode 

     *            精度取值方式. 

     * @return 精度計算後的數據. 

     */  

    public static double round(double value, int scale, int roundingMode) {  

        BigDecimal bd = new BigDecimal(value);  

        bd = bd.setScale(scale, roundingMode);  

        double d = bd.doubleValue();  

        bd = null;  

        return d;  

    }  

  

    /** 

     * 測試用的main方法. 

     *  

     * @param argc 

     *            運行參數. 

     */  

    public static void main(String[] argc) {  

        //下面都以保留2位小數為例  

          

        //ROUND_UP  

        //只要第2位後面存在大於0的小數,則第2位就+1  

        System.out.println(round(12.3401,2,BigDecimal.ROUND_UP));//12.35  

        System.out.println(round(-12.3401,2,BigDecimal.ROUND_UP));//-12.35  

        //ROUND_DOWN  

        //與ROUND_UP相反  

        //直接捨棄第2位後面的所有小數  

        System.out.println(round(12.349,2,BigDecimal.ROUND_DOWN));//12.34  

        System.out.println(round(-12.349,2,BigDecimal.ROUND_DOWN));//-12.34  

        //ROUND_CEILING  

        //如果數字0 則和ROUND_UP作用一樣  

        //如果數字0 則和ROUND_DOWN作用一樣  

        System.out.println(round(12.3401,2,BigDecimal.ROUND_CEILING));//12.35  

        System.out.println(round(-12.349,2,BigDecimal.ROUND_CEILING));//-12.34  

        //ROUND_FLOOR  

        //如果數字0 則和ROUND_DOWN作用一樣  

        //如果數字0 則和ROUND_UP作用一樣  

        System.out.println(round(12.349,2,BigDecimal.ROUND_FLOOR));//12.34  

        System.out.println(round(-12.3401,2,BigDecimal.ROUND_FLOOR));//-12.35  

        //ROUND_HALF_UP [這種方法最常用]  

        //如果第3位數字=5,則第2位數字+1  

        //備註:只看第3位數字的值,不會考慮第3位之後的小數的  

        System.out.println(round(12.345,2,BigDecimal.ROUND_HALF_UP));//12.35  

        System.out.println(round(12.3449,2,BigDecimal.ROUND_HALF_UP));//12.34  

        System.out.println(round(-12.345,2,BigDecimal.ROUND_HALF_UP));//-12.35  

        System.out.println(round(-12.3449,2,BigDecimal.ROUND_HALF_UP));//-12.34  

        //ROUND_HALF_DOWN  

        //如果第3位數字=5,則做ROUND_UP  

        //如果第3位數字5,則做ROUND_DOWN  

        System.out.println(round(12.345,2,BigDecimal.ROUND_HALF_DOWN));//12.35  

        System.out.println(round(12.3449,2,BigDecimal.ROUND_HALF_DOWN));//12.34  

        System.out.println(round(-12.345,2,BigDecimal.ROUND_HALF_DOWN));//-12.35  

        System.out.println(round(-12.3449,2,BigDecimal.ROUND_HALF_DOWN));//-12.34  

        //ROUND_HALF_EVEN  

        //如果第3位是偶數,則做ROUND_HALF_DOWN  

        //如果第3位是奇數,則做ROUND_HALF_UP  

        System.out.println(round(12.346,2,BigDecimal.ROUND_HALF_EVEN));//12.35  

        System.out.println(round(12.345,2,BigDecimal.ROUND_HALF_EVEN));//12.35  

    }  

}

 如果要求精確控制位數,推薦使用BigDecimal,這是在JDK1.4版本之後推薦的一個處理精度的類。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/286043.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-22 16:07
下一篇 2024-12-22 16:07

相關推薦

  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • Python官網中文版:解決你的編程問題

    Python是一種高級編程語言,它可以用於Web開發、科學計算、人工智慧等領域。Python官網中文版提供了全面的資源和教程,可以幫助你入門學習和進一步提高編程技能。 一、Pyth…

    編程 2025-04-29
  • Java Bean載入過程

    Java Bean載入過程涉及到類載入器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean載入的過程。 一、類載入器 類載入器是Java虛擬機…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • 如何解決WPS保存提示會導致宏不可用的問題

    如果您使用過WPS,可能會碰到在保存的時候提示「文件中含有宏,保存將導致宏不可用」的問題。這個問題是因為WPS在默認情況下不允許保存帶有宏的文件,為了解決這個問題,本篇文章將從多個…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字元串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字元串中是否存在多個指定字元: 一、字元串遍歷 字元串是Java編程中非常重要的一種數據類型。要判斷字元串中是否存在多個指定字元…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29

發表回復

登錄後才能評論