1. 程式人生 > >java 浮點計算 處理方案

java 浮點計算 處理方案

32位微處理器開始支援浮點運算,java語言自己支援浮點運算。

浮點運算導致的問題有:四捨五入出錯,四則運算出錯,運算結果格式古怪等等。

問題的原因 其實簡單:

1.計算機儲存的數是近似數,同時為了顯示不會太長根據需要會進行適當的舍操作

2.計算機儲存的數是不連續的,這不同於實數,如果一個數不是計算機可完全表示的數則會找一個最接近的數來表示該數

3.四則運算,特別是除數被被除數相差很大等就會把上面存在的誤差放大很多

4.各種程式語言的基本資料型別基本都有表示範圍,所以存在溢位和越界的問題

錯誤示例:

123.3-》123.29999999999999;0.5/3-》0.16666666666666666;(1/2f)*840=168.00000250339508

java語言提供了對浮點數的支援,下面列舉簡單的幾個點:

1.型別:java浮點格式的 基本資料型別有float,doulbe兩

3.精度: 浮點數值的精度是其有效數值中的有效數字個數的度量;double比float有更高的精度;表示1/3時,double的字面值0.3333333333333333比float的字面值0.3333333f有更高的精度

4.運演算法則:雙目運算中有一個浮點數是double型則運算時會先將float型轉換成double再計算最終是double型數; java中分嚴格和非嚴格浮點運算,前者中間結果會適當舍入,在所以jvm上計算結果會一樣,後者則通過低層硬體等實現中間過程的準確計算,應用於有特殊要求的地方。

針對java語言,使用現有java.math.BigDecimal作為橋樑可以解決,即數字要進行舍入或進行四則運算前先用BigDecimal封裝再呼叫它的方法完成後再轉換回原來的資料型別就行了。新問題是每次轉換很麻煩,當然自己寫個類封裝四則運算以及定義四捨五入方式就好了 。下面是參考程式碼(網路資源),想法是一致的:

package com.strongit.financesys.util;

import java.math.BigDecimal;

/**
 * 
 * 由於Java的簡單型別不能夠精確的對浮點數進行運算,這個工具類提供精
 * 
 * 確的浮點數運算,包括加減乘除和四捨五入。

 * 
 
*/


publicclass Arithmetic {

    
// 預設除法運算精度

    
privatestaticfinalint DEF_DIV_SCALE =10;

    
// 這個類不能例項化

    
private Arithmetic() {

    }


    
/**
     * 
     * 提供精確的加法運算。

     * 
     * 
@param v1
     *            被加數

     * 
     * 
@param v2
     *            加數
     * 
     * 
@return 兩個引數的和
     * 
     
*/


    
publicstaticdouble add(double v1, double v2) {

        BigDecimal b1 
=new BigDecimal(Double.toString(v1));

        BigDecimal b2 
=new BigDecimal(Double.toString(v2));

        
return b1.add(b2).doubleValue();

    }


    
/**
     * 
     * 提供精確的減法運算。

     * 
     * 
@param v1
     *            被減數

     * 
     * 
@param v2
     *            減數
     * 
     * 
@return 兩個引數的差
     * 
     
*/


    
publicstaticdouble sub(double v1, double v2) {

        BigDecimal b1 
=new BigDecimal(Double.toString(v1));

        BigDecimal b2 
=new BigDecimal(Double.toString(v2));

        
return b1.subtract(b2).doubleValue();

    }


    
/**
     * 
     * 提供精確的乘法運算。

     * 
     * 
@param v1
     *            被乘數

     * 
     * 
@param v2
     *            乘數
     * 
     * 
@return 兩個引數的積
     * 
     
*/


    
publicstaticdouble mul(double v1, double v2) {

        BigDecimal b1 
=new BigDecimal(Double.toString(v1));

        BigDecimal b2 
=new BigDecimal(Double.toString(v2));

        
return b1.multiply(b2).doubleValue();

    }


    
/**
     * 
     * 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到
     * 
     * 小數點以後10位,以後的數字四捨五入。

     * 
     * 
@param v1
     *            被除數

     * 
     * 
@param v2
     *            除數
     * 
     * 
@return 兩個引數的商
     * 
     
*/


    
publicstaticdouble div(double v1, double v2) {

        
return div(v1, v2, DEF_DIV_SCALE);

    }


    
/**
     * 
     * 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale引數指

     * 
     * 定精度,以後的數字四捨五入。

     * 
     * 
@param v1
     *            被除數

     * 
     * 
@param v2
     *            除數
     * 
     * 
@param scale
     *            表示表示需要精確到小數點以後幾位。

     * 
     * 
@return 兩個引數的商
     * 
     
*/


    
publicstaticdouble div(double v1, double v2, int scale) {

        
if (scale <0{

            
thrownew IllegalArgumentException(

            
"The scale must be a positive integer or zero");

        }


        BigDecimal b1 
=new BigDecimal(Double.toString(v1));

        BigDecimal b2 
=new BigDecimal(Double.toString(v2));

        
return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

    }


    
/**
     * 
     * 提供精確的小數位四捨五入處理。

     * 
     * 
@param v
     *            需要四捨五入的數字
     * 
     * 
@param scale
     *            小數點後保留幾位
     * 
     * 
@return 四捨五入後的結果
     * 
     
*/


    
publicstaticdouble round(double v, int scale) {

        
if (scale <0{

            
thrownew IllegalArgumentException(

            
"The scale must be a positive integer or zero");

        }


        BigDecimal b 
=new BigDecimal(Double.toString(v));

        BigDecimal one 
=new BigDecimal("1");

        
return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();

    }


}

這個程式碼目前能穩定的處理java浮點數運算問題,我希望能共享大家對其改進後的成果。。。

相關推薦

java 計算 處理方案

32位微處理器開始支援浮點運算,java語言自己支援浮點運算。 浮點運算導致的問題有:四捨五入出錯,四則運算出錯,運算結果格式古怪等等。 問題的原因 其實簡單: 1.計算機儲存的數是近似數,同時為了顯示不會太長根據需要會進行適當的舍操作 2.計算機儲存的數是不連續的,這不同

點數的那些坑,Java中的金額處理方案

Java中的浮點數由於精度問題經常出現意料之外的結果,而我們又不得不和RMB打交道的 有任何問題,歡迎Email to: [email protected] 1.舉個栗子: public static void main(String[] args) {Syst

JS計算的問題以及處理

在使用浮點計算的時候明明1.56+0.07=1.63,小學生都會算的,可是計算機為什麼算出來很長一段數字呢? 因為JavaScript 裡的數字是採用 IEEE 754 標準的 64 位雙精度浮點數。該規範定義了浮點數的格式。 不說話直接上程式碼看看: <div&

java 數值計算誤差

問題 當我們執行如下函式時 public void test() { System.out.println(2.0-1.1); //=>0.8999999999999999 } 我們發現其結果並非是我們預想的0.9 原因 其主要原因是浮點數值採用二進

JS計算精度問題分析與解決

href 動態控制 hub 截斷 max fix math floating 方案 問題描述 在JS計算四則運算時會遇到精度丟失的問題,會引起諸多問題,看看以下例子: 例如:在chrome控制臺輸入 0.1 + 0.7 輸出結果是 0.7999999999999999 例如

DSP定點與計算

精度 變量 技術分享 高精 轉換關系 例如 align 進制 給定 在定點DSP芯片中,采用定點數進行數值運算,其操作數一般采用整型數來表示。一個整型數的最大表示範圍取決於DSP芯片所給定的字長,一般為16位或24位。顯然,字長越長,所能表示的數的範圍越大,精度也越高。如無

JS計算問題

本文轉自:https://www.cnblogs.com/Stephenchao/p/5743805.html 用js進行浮點數計算,結果可能會“超出預期”,大部分計算結果還是對的,但是我們可不想在計算這麼嚴謹的事情上還有意外的驚喜。比如: 0.3 + 0.6 = 0.89999999

計算

js浮點計算 方法一: 指定要保留的小數位數 (0.1+0.2).toFixed(1) = 0.3; 這個方法toFixed是進行四捨五入的也不是很精準,對於計算金額這種嚴謹的問題,不推薦使用,而且不通瀏覽器對toFixed的計算結果也存在差異。 方法二:

遍歷集合時出現異常:java.util.ConcurrentModificationException的處理方案

0.出現異常的原因:集合在迭代過程中對其中的元素進行修改操作。以下是解決方法1.java遍歷Map時,對其元素進行刪除package net.nie.test;  import java.util.HashMap;  import java.util.Iterator;  i

java基本類型(數值範圍):的底層表示定義,float計算快一些

方法 -1 att ieee754 符號位 無法 字符類 數值計算 小數 Java八種基本類型: 六種數字類型(四個整數型,兩個浮點型), 一種字符類型, 一種布爾型。 詳細例如以下 1、整數:包含int,short,byte,long

Java型資料Float和Double進行精確計算的問題

Java中浮點型資料Float和Double進行精確計算的問題 來源  https://www.cnblogs.com/banxian/p/3781130.html   一、浮點計算中發生精度丟失       大概

Java型數據Float和Double進行精確計算的問題

file 2.4 設置 數據 有一個 對比 科學 單個 做到 Java中浮點型數據Float和Double進行精確計算的問題 來源 https://www.cnblogs.com/banxian/p/3781130.html 一、浮點計算中發生精度丟失 大

java中金額(表示)的計算

 java中進行金額的計算經常浮點數丟失精度,造成這種問題的原因應該與cpu對浮點數的計算方式有關,有下面的介紹:從原理上來講,任何一門語言對於浮點數的計算都是不精確的。因為現在的Computer都是基於二進位制數來儲存計算的。例如計算8+3時,Computer會轉換為二進位

java基本型別(數值範圍):的底層表示定義,float計算快一些

Java八種基本型別: 六種數字型別(四個整數型,兩個浮點型), 一種字元型別, 一種布林型。 具體如下 1、整數:包括int,short,byte,long 2、浮點型:float,d

java處理型別的加減乘除法出現小數點精度錯亂的解決方法

如果你在java裡面執行一下一段程式碼,你會發現會出現錯亂的小數點: double d1 = 100.0234; double d2 = 12.0652;

Java應用集群下的定時任務處理方案(mysql)

運行 1.0 null 都是 bean -a 刷新 bat 任務調度 今天來說一個Java多機部署下定時任務的處理方案。 需求: 有兩臺服務器同時部署了同一套代碼, 代碼中寫有spring自帶的定時任務,但是每次執行定時任務時只需要一臺機器去執行。 當拿到這個需求時我腦子中

字節數組byte[]和整型,型數據的轉換——Java代碼

amp gravity img 如何 class 機器 保存 clas -m 近期在寫C++ socket和java socket之間的通信程序,涉及到整數浮點數的傳輸。須要從字節數組還原數據,查了一些資料。總結例如以下 1. 整數和浮點數的機器表示 在機器

Java復習之整型自動轉換成

自動 string 自動轉換 oat 整型 fop ring java 轉換 class DataCon {   public static void main(String args[])   {     int nop1=2;     float fop2=2.25f;

java JVM常見的四大異常及處理方案

maxperm 就是 locate stack 修飾 gpo 異常 native 思路 區域 作用 異常 控制參數 解決思路 java堆 存放對象的實例。 java.lang.OutOfMemory Error:Java heap space -Xms(初始化堆

Java 使用BigDecimal類處理高精度計算

positive urn 使用 println highlight 轉換 posit exception val Java在java.math包中提供的API類BigDecimal,用來對超過16位有效位的數進行精確的運算。雙精度浮點型變量double可以處理16位有效數,