java double 兩位_java double 保留兩位小數

java保留兩位小數問題:

方式一:

四舍五入

double?? f?? =?? 111231.5585;

BigDecimal?? b?? =?? new?? BigDecimal(f);

double?? f1?? =?? b.setScale(2,?? BigDecimal.ROUND_HALF_UP).doubleValue();

保留兩位小數

---------------------------------------------------------------

方式二:

java.text.DecimalFormat?? df?? =new?? java.text.DecimalFormat("#.00");

df.format(你要格式化的數字);

例:new java.text.DecimalFormat("#.00").format(3.1415926)

#.00 表示兩位小數 #.0000四位小數 以此類推...

方式三:

double d = 3.1415926;

String result = String .format("%.2f");

%.2f %. 表示 小數點前任意位數?? 2 表示兩位小數 格式后的結果為f 表示浮點型

方式四:

NumberFormat ddf1=NumberFormat.getNumberInstance() ;

void setMaximumFractionDigits(int digits)

digits 顯示的數字位數

為格式化對象設定小數點后的顯示的最多位,顯示的最后位是舍入的

import java.text.* ;

import java.math.* ;

class TT

{

public static void main(String args[])

{ double x=23.5455;

NumberFormat ddf1=NumberFormat.getNumberInstance() ;

ddf1.setMaximumFractionDigits(2);

String s= ddf1.format(x) ;

System.out.print(s);

}

}

---------------------------------------------------------------------------------------------------------

有一篇:

(1)、浮點數精確計算

勝利油田三流合一項目中一直存在一個問題,就是每次報表統計的物資金額和實際的金額要差那么幾分錢,和實際金額不一致,讓客戶覺得總是不那么舒服,原因是因為我們使用java的浮點類型double來定義物資金額,并且在報表統計中我們經常要進行一些運算,但Java中浮點數(double、float)的計算是非精確計算,請看下面一個例子:

System.out.println(0.05 + 0.01);

System.out.println(1.0 - 0.42);

System.out.println(4.015 * 100);

System.out.println(123.3 / 100);

你的期望輸出是什么?可實際的輸出確實這樣的:

0.060000000000000005

0.5800000000000001

401.49999999999994

1.2329999999999999

這個問題就非常嚴重了,如果你有123.3元要購買商品,而計算機卻認為你只有123.29999999999999元,錢不夠,計算機拒絕交易。

(2)、四舍五入

是否可以四舍五入呢?當然可以,習慣上我們本能就會這樣考慮,但四舍五入意味著誤差,商業運算中可能意味著錯誤,同時Java中也沒有提供保留指定位數的四舍五入方法,只提供了一個Math.round(double d)和Math.round(float f)的方法,分別返回長整型和整型值。round方法不能設置保留幾位小數,我們只能象這樣(保留兩位):

public double round(double value){

return Math.round( value * 100 ) / 100.0;

}

但非常不幸的是,上面的代碼并不能正常工作,給這個方法傳入4.015它將返回4.01而不是4.02,如我們在上面看到的

4.015 * 100 = 401.49999999999994

因此如果我們要做到精確的四舍五入,這種方法不能滿足我們的要求。

還有一種方式是使用java.text.DecimalFormat,但也存在問題,format采用的舍入模式是ROUND_HALF_DOWN(舍入模式在下面有介紹),比如說4.025保留兩位小數會是4.02,因為.025距離”nearest neighbor”(.02和.03)長度是相等,向下舍入就是.02,如果是4.0251那么保留兩位小數就是4.03。

System.out.println(new java.text.DecimalFormat("0.00").format(4.025));

System.out.println(new java.text.DecimalFormat("0.00").format(4.0251));

輸出是

4.02

4.03

(3)、浮點數輸出(科學記數法)

Java浮點型數值在大于9999999.0就自動轉化為科學記數法來表示,我們看下面的例子:

System.out.println(999999999.04);

System.out.println(99999999.04);

System.out.println(10000000.01);

System.out.println(9999999.04);

輸出的結果如下:

9.9999999904E8

9.999999904E7

1.000000001E7

9999999.04

但有時我們可能不需要科學記數法的表示方法,需要轉換為字符串,還不能直接用toString()等方法轉換,很煩瑣。

BigDecimal介紹

BigDecimal是Java提供的一個不變的、任意精度的有符號十進制數對象。它提供了四個構造器,有兩個是用BigInteger構造,在這里我們不關心,我們重點看用double和String構造的兩個構造器(有關BigInteger詳細介紹請查閱j2se API文檔)。

(double?val)

Translates a double into a BigDecimal.

Translates the String representation of a BigDecimal into a BigDecimal.

BigDecimal(double)是把一個double類型十進制數構造為一個BigDecimal對象實例。

BigDecimal(String)是把一個以String表示的BigDecimal對象構造為BigDecimal對象實例。

習慣上,對于浮點數我們都會定義為double或float,但BigDecimal API文檔中對于BigDecimal(double)有這么一段話:

Note: the results of this constructor can be somewhat unpredictable. One might assume thatnew BigDecimal(.1)is exactly equal to .1, but it is actually equal to .10000000000000000555111512312578 27021181583404541015625. This is so because .1 cannot be represented exactly as a double (or, for that matter, as a binary fraction of any finite length). Thus, the long value that is being passed?in?to the constructor is not exactly equal to .1, appearances notwithstanding.

The (String) constructor, on the other hand, is perfectly predictable:new BigDecimal(".1")is?exactly?equal to .1, as one would expect. Therefore, it is generally recommended that the (String) constructor be used in preference to this one

下面對這段話做簡單解釋:

注意:這個構造器的結果可能會有不可預知的結果。有人可能設想new BigDecimal(.1)等于.1是正確的,但它實際上是等于.1000000000000000055511151231257827021181583404541015625,這就是為什么.1不能用一個double精確表示的原因,因此,這個被放進構造器中的長值并不精確的等于.1,盡管外觀看起來是相等的。

然而(String)構造器,則完全可預知的,new BigDecimal(“.1”)如同期望的那樣精確的等于.1,因此,(String)構造器是被優先推薦使用的。

看下面的結果:

System.out.println(new BigDecimal(123456789.02).toString());

System.out.println(new BigDecimal("123456789.02").toString());

輸出為:

123456789.01999999582767486572265625

123456789.02

現在我們知道,如果需要精確計算,非要用String來夠造BigDecimal不可!

實現方案

現在我們已經知道怎么解決這個問題了,原則上是使用BigDecimal(String)構造器,我們建議,在商業應用開發中,涉及金額等浮點數計算的數據,全部定義為String,數據庫中可定義為字符型字段,在需要使用這些數據進行運算的時候,使用BigDecimal(String)構造BigDecimal對象進行運算,保證數據的精確計算。同時避免了科學記數法的出現。如果科學記數表示法在應用中不是一種負擔的話,可以考慮定義為浮點類型。

這里我們提供了一個工具類,定義浮點數的加、減、乘、除和四舍五入等運算方法。以供參考。

源文件MathExtend.java:

import java.math.BigDecimal;

public class MathExtend

{

//默認除法運算精度

private static final int DEFAULT_DIV_SCALE = 10;

/**

*提供精確的加法運算。

* @param v1

* @param v2

* @return兩個參數的和

*/

public static double 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兩個參數數學加和,以字符串格式返回

*/

public static String add(String v1, String v2)

{

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

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

}

/**

*提供精確的減法運算。

* @param v1

* @param v2

* @return兩個參數的差

*/

public static double subtract(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兩個參數數學差,以字符串格式返回

*/

public static String subtract(String v1, String v2)

{

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

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

}

/**

*提供精確的乘法運算。

* @param v1

* @param v2

* @return兩個參數的積

*/

public static double multiply(double v1, double v2)

{

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

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

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

}

/**

*提供精確的乘法運算

* @param v1

* @param v2

* @return兩個參數的數學積,以字符串格式返回

*/

public static String multiply(String v1, String v2)

{

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

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

}

/**

*提供(相對)精確的除法運算,當發生除不盡的情況時,精確到

*小數點以后10位,以后的數字四舍五入,舍入模式采用ROUND_HALF_EVEN

* @param v1

* @param v2

* @return兩個參數的商

*/

public static double divide(double v1, double v2)

{

return divide(v1, v2, DEFAULT_DIV_SCALE);

}

/**

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

*定精度,以后的數字四舍五入。舍入模式采用ROUND_HALF_EVEN

* @param v1

* @param v2

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

* @return兩個參數的商

*/

public static double divide(double v1,double v2, int scale)

{

return divide(v1, v2, scale, BigDecimal.ROUND_HALF_EVEN);

}

/**

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

*定精度,以后的數字四舍五入。舍入模式采用用戶指定舍入模式

* @param v1

* @param v2

* @param scale表示需要精確到小數點以后幾位

* @param round_mode表示用戶指定的舍入模式

* @return兩個參數的商

*/

public static double divide(double v1,double v2,int scale, int round_mode){

if(scale < 0)

{

throw new 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, round_mode).doubleValue();

}

/**

*提供(相對)精確的除法運算,當發生除不盡的情況時,精確到

*小數點以后10位,以后的數字四舍五入,舍入模式采用ROUND_HALF_EVEN

* @param v1

* @param v2

* @return兩個參數的商,以字符串格式返回

*/

public static String divide(String v1, String v2)

{

return divide(v1, v2, DEFAULT_DIV_SCALE);

}

/**

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

*定精度,以后的數字四舍五入。舍入模式采用ROUND_HALF_EVEN

* @param v1

* @param v2

* @param scale表示需要精確到小數點以后幾位

* @return兩個參數的商,以字符串格式返回

*/

public static String divide(String v1, String v2, int scale)

{

return divide(v1, v2, DEFAULT_DIV_SCALE, BigDecimal.ROUND_HALF_EVEN);

}

/**

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

*定精度,以后的數字四舍五入。舍入模式采用用戶指定舍入模式

* @param v1

* @param v2

* @param scale表示需要精確到小數點以后幾位

* @param round_mode表示用戶指定的舍入模式

* @return兩個參數的商,以字符串格式返回

*/

public static String divide(String v1, String v2, int scale, int round_mode)

{

if(scale < 0)

{

throw new IllegalArgumentException("The scale must be a positive integer or zero");

}

BigDecimal b1 = new BigDecimal(v1);

BigDecimal b2 = new BigDecimal(v2);

return b1.divide(b2, scale, round_mode).toString();

}

/**

*提供精確的小數位四舍五入處理,舍入模式采用ROUND_HALF_EVEN

* @param v需要四舍五入的數字

* @param scale小數點后保留幾位

* @return四舍五入后的結果

*/

public static double round(double v,int scale)

{

return round(v, scale, BigDecimal.ROUND_HALF_EVEN);

}

/**

*提供精確的小數位四舍五入處理

* @param v需要四舍五入的數字

* @param scale小數點后保留幾位

* @param round_mode指定的舍入模式

* @return四舍五入后的結果

*/

public static double round(double v, int scale, int round_mode)

{

if(scale<0)

{

throw new IllegalArgumentException("The scale must be a positive integer or zero");

}

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

return b.setScale(scale, round_mode).doubleValue();

}

/**

*提供精確的小數位四舍五入處理,舍入模式采用ROUND_HALF_EVEN

* @param v需要四舍五入的數字

* @param scale小數點后保留幾位

* @return四舍五入后的結果,以字符串格式返回

*/

public static String round(String v, int scale)

{

return round(v, scale, BigDecimal.ROUND_HALF_EVEN);

}

/**

*提供精確的小數位四舍五入處理

* @param v需要四舍五入的數字

* @param scale小數點后保留幾位

* @param round_mode指定的舍入模式

* @return四舍五入后的結果,以字符串格式返回

*/

public static String round(String v, int scale, int round_mode)

{

if(scale<0)

{

throw new IllegalArgumentException("The scale must be a positive integer or zero");

}

BigDecimal b = new BigDecimal(v);

return b.setScale(scale, round_mode).toString();

}

}

BigDecimal舍入模式(Rounding mode)介紹:

BigDecimal定義了一下舍入模式,只有在作除法運算或四舍五入時才用到舍入模式,下面簡單介紹,詳細請查閱J2se API文檔

static?int

Rounding mode to round towards positive infinity.

向正無窮方向舍入

static?int

Rounding mode to round towards zero.

向零方向舍入

static?int

Rounding mode to round towards negative infinity.

向負無窮方向舍入

static?int

Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round down.

向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向下舍入,?例如1.55?保留一位小數結果為1.5

static?int

Rounding mode to round towards the "nearest neighbor" unless both neighbors are equidistant, in which case, round towards the even neighbor.

向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,如果保留位數是奇數,使用ROUND_HALF_UP,如果是偶數,使用ROUND_HALF_DOWN

static?int

Rounding mode to round towards "nearest neighbor" unless both neighbors are equidistant, in which case round up.

向(距離)最近的一邊舍入,除非兩邊(的距離)是相等,如果是這樣,向上舍入, 1.55保留一位小數結果為1.6

static?int

Rounding mode to assert that the requested operation has an exact result, hence no rounding is necessary.

計算結果是精確的,不需要舍入模式

static?int

Rounding mode to round away from zero.

向遠離0的方向舍入

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/260316.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/260316.shtml
英文地址,請注明出處:http://en.pswp.cn/news/260316.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

fatal error C1902: 程序數據庫管理器不匹配;請檢查安裝解決

終于找到原因了&#xff0c;原來是我安裝的字體渲染&#xff0c;并且采用注冊表的加載方式&#xff01;改掉就好了&#xff01;上天哪&#xff0c;這是怎么影響到的 卸載MacType程序后&#xff0c;進行嘗試&#xff01; VS2008 和 VS2010 又能用了&#xff01; 我想求教育。。。…

一分鐘明確 VS manifest 原理

什么是vs 程序的manifest文件 manifest 是VS程序用來標明所依賴的side-by-side組建,如ATL, CRT等的清單。 為什么要有manifest文件 一臺pc上&#xff0c;用一組建往往會有不止一個版本號&#xff08;c:/windows/winsxs或系統文件夾下&#xff09;&#xff0c;程序在載入的時候&…

[譯]多線程網絡服務模型

2019獨角獸企業重金招聘Python工程師標準>>> 多線程網絡服務模型 /*** 謹獻給Yoyo** 原文出處&#xff1a;https://www.toptal.com/software/guide-to-multi-processing-network-server-models* author dogstar.huang <chanzonghuanggmail.com> 2016-04-02*/作…

likely(x)與unlikely(x)函數,即__builtin_expect的使用

轉載自&#xff1a;http://velep.com/archives/795.html 本文講的likely()和unlikely()兩個宏&#xff0c;在linux內核代碼和一些應用中可常見到它們的身影。實質上&#xff0c;這兩個宏是關于GCC編譯器內置宏__builtin_expect的使用。顧名思義&#xff0c;likely()指“很有可能…

java mvc引擎_SpringMvc+JavaConfig+Idea 搭建項目

1.介紹之前搭建SpringMvc項目要配置一系列的配置文件&#xff0c;比如web.xml,applicationContext.xml,dispatcher.xml。Spring 3.X之后推出了基于JavaConfig方式以及注解的形式的配置。在一定程度上簡化了Spring項目的配置。近幾年特別火的SpringBoot&#xff0c;大大的簡化了…

window.parent和window.opener區別

下面一段代碼是關于window.parent和window.opener區別 來講的&#xff0c;我們如果要用到iframe的值傳到另一框架就要用到window.opener.document.getElementById(name).value uvalue;這種形式哦。 window.parent能獲取一個框架的父窗口或父框架。頂層窗口的parent引用的是它本…

極域電子書包課堂管理系統_【君蓮微訊】君蓮學校(小學部)開展電子書包第13共同體數學研討活動...

借 助 媒 體 技 術豐 富 圖 形 認 識君蓮學校(小學部)開展電子書包共同體 數學研討活動 2020年12月2日下午&#xff0c;君蓮學校(小學部)開展了以“借助媒體技術 豐富圖形認識”為主題的閔行區電子書包第13共同體的數學研討活動。共同體學校教師代表、學校電子書包項目組主管朱…

python批量改動指定文件夾文件名稱

這小樣例僅僅要是說明用python怎么批量改動指定文件夾的文件名稱&#xff1a; 記得要把腳本跟改動的文件放在同一個文件夾下 #encoding:utf-8 import os import sys files os.listdir(D:\\1) #路徑能夠自己for name in files:a os.path.splitext(name)if a[1] .txt: #txt能夠…

Linux vmstat命令實戰詳解

vmstat命令是最常見的Linux/Unix監控工具&#xff0c;可以展現給定時間間隔的服務器的狀態值,包括服務器的CPU使用率&#xff0c;內存使用&#xff0c;虛擬內存交換情況,IO讀寫情況。這個命令是我查看Linux/Unix最喜愛的命令&#xff0c;一個是Linux/Unix都支持&#xff0c;二是…

python的基礎網絡編程是下列_Python入門基礎之網絡編程、socket編程、TCP、UDP編程...

忙了兩天&#xff0c;繼續更文&#xff01;希望多多支持。套接字套接字是一種具有之前所說的"通訊端點"概念的計算機網絡數據結構。網絡化的應用程序在開始任何通訊之前都必需要創建套接字。套接字有三種&#xff1a;1、 AF_UNIX(在 POSIX1.g 標準中也叫 AF_LOCAL)&a…

java 入門 博客園_javaweb入門

復習&#xff1a;css的常用樣式&#xff1a;borderbackgroundpaddingmarginfloatposition 定位top left確定div在頁面中的位置&#xff0c;這兩個值可以為負數。cssdiv 布局方式cssdivtable 先由div劃分大塊兒&#xff0c;再由table進行整齊布局。下拉列表&#xff1a;層疊的布…

以ThreadStart方式實現多線程

3.1 使用ThreadStart委托 這里先以一個例子體現一下多線程帶來的好處&#xff0c;首先在Message類中建立一個方法ShowMessage()&#xff0c;里面顯示了當前運行線程的Id&#xff0c;并使用Thread.Sleep&#xff08;int ) 方法模擬部分工作。在main()中通過ThreadStart委托綁定M…

管理思考

管理基礎 分活 分錢 分責任 分權 安人(安排 配置) 流程 標準 考核 治人(協調 指揮 控制) 社會越來越復雜 分工越來越復雜 合作越來越重要 目標一定要一致共同的意愿共識 需要大家參與管理 業務劃分 責任劃分 流程梳理 如何合作做好安全工作 安全服務因為不承擔責任 責任主體是管…

我的atom插件

atom插件實在是太多了&#xff0c;下面就說說我的插件 1.minimap 右邊的小地圖&#xff0c;和sublime里面的差不多&#xff1b; 2.open-in-browser 右擊默認瀏覽器打開&#xff1b; 3.emmet 這個不用多說吧&#xff0c;html快速編譯 4.git-plus 直接在atom提交代碼&#xff0…

python統計英文句子每個單詞字數_Python小書3-文本英文單詞統計

之前寫Python Web小書第三小節本來用的垃圾郵件的案例三郎&#xff1a;Python貝葉斯推理垃圾郵件分類?zhuanlan.zhihu.com后來發現里面的東西&#xff0c;涉及到概率&#xff0c;程序太復雜了。。。哈哈哈所以就想著&#xff0c;哪天重寫一下&#xff0c;選來選去&#xff0c;…

java9特性_96.java基礎10(java9/10/11新特性)

126.java 9 新特性1(模塊化功能):1.java模塊化2.java 交互式環境jshell3.泛型package com.atguigu.java;import org.junit.Test;import java.io.IOException;import java.io.InputStreamReader;import java.net.MalformedURLException;import java.net.URL;import java.util.Ar…

MonoRail - 簡介 [基礎知識篇]

MonoRail - 簡介 起源 MonoRail是一個.NET的MVC web開發框架, 原名Castle On Rails, 是CastleProject的一個子項目. 作者hammett在使用過Ruby On Rails后, 覺得非常棒, 他希望在享受ror的開發模式的同時能使用大量現有的資源, 于是就用.NET寫出了一個Castle On Rails. 后來ror那…

結對編程(黃金點游戲)

我扮演的角色是駕駛員 一、結對伙伴 領航員&#xff1a;趙峻 作業地址見我的博客。 二、代碼地址 https://coding.net/u/k2048/p/huangjindian/git/blob/master/main.c 三、總結 1、個人總結 本次作業我扮演駕駛員&#xff0c;趙峻扮演領航員&#xff0c;我負責算法實現以及代碼…

qtgl 鼠標平移 c++_羅技真愛粉的MX Master 3無線鼠標體驗

?這是一篇關于羅技MX Master3的曬單&#xff0c;順帶也翻出我的庫存清潔整理一下吧。在決定購買一款新鼠標的時候&#xff0c;我的第一目標其實是MX Vertical垂直鼠標&#xff0c;不過MX Vertical目前優勢只在外形上&#xff0c;在MX系列中明顯屬于低配&#xff0c;自由滾輪、…

java實驗指導書(實驗四)答案_java程序設計實驗指導書答案

? 狗生活在陸地上(是一種陸生動物)&#xff0c;既是哺乳類的也是肉食性的。狗通常的時候和人打招呼會通過“搖搖尾巴”&#xff0c;在被撫摸感到舒服的時候&#xff0c;會“旺旺叫”&#xff0c;而在受到驚嚇情緒煩躁時&#xff0c;會發出“嗚嗚”聲&#xff1b;? 貓也生活在…