BigDecimal的數(shù)據(jù)轉(zhuǎn)換-java 計(jì)算數(shù)據(jù)(1)

Bigdecimal 數(shù)據(jù)轉(zhuǎn)換精度缺失

使用 new BigDecimal()、.valueof() 和 new BigDecimal("[字符串]")的區(qū)別

構(gòu)造 BigDecimal 對(duì)象常用以下方法:
BigDecimal BigDecimal(double d); //不允許使用
BigDecimal BigDecimal(String s); //常用,推薦使用
static BigDecimal valueOf(double d); //常用,推薦使用
其原因有

  1. double 參數(shù)的構(gòu)造方法,不允許使用!!!!因?yàn)樗荒芫_的得到相應(yīng)的值;
  2. String 構(gòu)造方法是完全可預(yù)知的: 寫入 new BigDecimal("0.1") 將創(chuàng)建一個(gè) BigDecimal,它正好等于預(yù)期的0.1; 因此,通常建議優(yōu)先使用 String 構(gòu)造方法;
  3. 靜態(tài)方法 valueOf(double val) 內(nèi)部實(shí)現(xiàn),仍是將 double 類型轉(zhuǎn)為 String 類型; 這通常是將 double(或float)轉(zhuǎn)化為 BigDecimal 的首選方法;
    如下代碼測(cè)試操作:
public class BigDecimalDemo {
    public static void main(String[] args) {
        Double v1 = 2.43;
        Double v2 = 4.0;
        System.out.println(new BigDecimal(v1));
        System.out.println(new BigDecimal(v2));
        System.out.println(new BigDecimal(v1.toString()));
        System.out.println(new BigDecimal(v2.toString()));
        System.out.println(BigDecimal.valueOf(v1));
        System.out.println(BigDecimal.valueOf(v2));
    }
}

以上輸出的結(jié)果是:

2.430000000000000159872115546022541821002960205078125
4
2.43
4.0
2.43
4.0

從結(jié)果可以看的出來直接 new BigDecimal()的情況會(huì)出現(xiàn)數(shù)據(jù)精準(zhǔn)度丟失的情況
而. valueof 和 new 字符串的形式卻不會(huì)使精度丟失
我們可以看一下他的源碼:

/**
     * Translates a {@code double} into a {@code BigDecimal}, using
     * the {@code double}'s canonical string representation provided
     * by the {@link Double#toString(double)} method.
     *
     * <p><b>Note:</b> This is generally the preferred way to convert
     * a {@code double} (or {@code float}) into a
     * {@code BigDecimal}, as the value returned is equal to that
     * resulting from constructing a {@code BigDecimal} from the
     * result of using {@link Double#toString(double)}.
     *
     * @param  val {@code double} to convert to a {@code BigDecimal}.
     * @return a {@code BigDecimal} whose value is equal to or approximately
     *         equal to the value of {@code val}.
     * @throws NumberFormatException if {@code val} is infinite or NaN.
     * @since  1.5
     */
    public static BigDecimal valueOf(double val) {
        // Reminder: a zero double returns '0.0', so we cannot fastpath
        // to use the constant ZERO.  This might be important enough to
        // justify a factory approach, a cache, or a few private
        // constants, later.
        return new BigDecimal(Double.toString(val));
    }
    

valueof 的形式是將 double 直接 tostring 為一個(gè)字符串的形式進(jìn)行轉(zhuǎn)換的

BigDecimal 的大小比較

BigDecimal是Java里精確計(jì)算的類枝恋,下面說一下兩個(gè)BigDecimal對(duì)象大小,相等的判斷。
一般的對(duì)象用equals,但是BigDecimal比較特殊讯壶,舉個(gè)例子:

public static void main(String[] args) {
        BigDecimal a = new BigDecimal("10.00");
        BigDecimal b = new BigDecimal("10");

        //equals方式
        System.out.println(a.equals(b)); //結(jié)果為: false

        //toPlainString再equals
        System.out.println(a.toPlainString().equals(b.toPlainString())); //結(jié)果為: false

        //longValue方式
        System.out.println(a.longValue() == b.longValue()); //結(jié)果為: true

        //compareTo
        System.out.println(a.compareTo(b) == 0); //結(jié)果為: true
    }

看似使用 Long 數(shù)據(jù)類型進(jìn)行比較也可以但是我們看下一個(gè)例子:

 public static void main(String[] args) {
        BigDecimal a = new BigDecimal("10.300003");
        BigDecimal b= new BigDecimal(10.300003);

        System.out.println(b.equals(a)); //false  
        System.out.println(b.toPlainString().equals(a.toPlainString())); //false  
        System.out.println(b.longValue() == a.longValue()); //true  
        System.out.println(b.compareTo(a) == 0); //false  
    }

為什么compareTo方法不可以了,而longValue方式卻還是OK的湾盗。讓我們打印一下伏蚊。

public static void main(String[] args) {
        BigDecimal a = new BigDecimal("10.300003");
        BigDecimal b= new BigDecimal(10.300003);

        System.out.println(b.equals(a)); //false  
        System.out.println(b.toPlainString().equals(a.toPlainString())); //false  
        System.out.println(b.longValue() == a.longValue()); //true
        System.out.println("b.longValue():"+b.longValue());
        System.out.println("a.longValue():"+a.longValue());
        System.out.println(b.compareTo(a) == 0); //false
    }

而輸出的結(jié)果令我懵逼

false
false
true
b.longValue():10
a.longValue():10
false

我們可以看出longvalue 的結(jié)果是沒有小數(shù)點(diǎn)的所以對(duì) BigDecimal 數(shù)據(jù)類型進(jìn)行比較的時(shí)候還是使用"compareTo"方法

總結(jié): 當(dāng)我們需要使用BigDecimal 進(jìn)行數(shù)據(jù)轉(zhuǎn)換時(shí)一定要注意轉(zhuǎn)換的數(shù)據(jù)類型以及大小比較的唯一方法我們可以對(duì)它的值進(jìn)行<或者>的判斷如:

  public static void main(String[] args) {
        BigDecimal a = new BigDecimal("10.300003");
        BigDecimal b=  BigDecimal.valueOf(10.3);

        System.out.println(b.compareTo(a) < 0); //true
        System.out.println(b.compareTo(a) > 0); //false
    }

最后:感謝大家的閱讀

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市格粪,隨后出現(xiàn)的幾起案子躏吊,更是在濱河造成了極大的恐慌,老刑警劉巖帐萎,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件比伏,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡疆导,警方通過查閱死者的電腦和手機(jī)赁项,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來澈段,“玉大人悠菜,你說我怎么就攤上這事“芨唬” “怎么了悔醋?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長囤耳。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么充择? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任德玫,我火速辦了婚禮,結(jié)果婚禮上椎麦,老公的妹妹穿的比我還像新娘宰僧。我一直安慰自己,他們只是感情好观挎,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布琴儿。 她就那樣靜靜地躺著,像睡著了一般嘁捷。 火紅的嫁衣襯著肌膚如雪造成。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天雄嚣,我揣著相機(jī)與錄音晒屎,去河邊找鬼。 笑死缓升,一個(gè)胖子當(dāng)著我的面吹牛鼓鲁,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播港谊,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼骇吭,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了歧寺?” 一聲冷哼從身側(cè)響起燥狰,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎成福,沒想到半個(gè)月后碾局,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡奴艾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年净当,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蕴潦。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡像啼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出潭苞,到底是詐尸還是另有隱情忽冻,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布此疹,位于F島的核電站僧诚,受9級(jí)特大地震影響遮婶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜湖笨,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一旗扑、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慈省,春花似錦臀防、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽弄痹。三九已至蛮瞄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留篡悟,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓匾寝,卻偏偏與公主長得像搬葬,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子艳悔,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容

  • 一急凰、Java 簡介 Java是由Sun Microsystems公司于1995年5月推出的Java面向?qū)ο蟪绦蛟O(shè)計(jì)...
    子非魚_t_閱讀 4,206評(píng)論 1 44
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法猜年,內(nèi)部類的語法抡锈,繼承相關(guān)的語法,異常的語法乔外,線程的語...
    子非魚_t_閱讀 31,664評(píng)論 18 399
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 11,007評(píng)論 6 13
  • 寫在云端 我要練就一雙無畏的雙眼 在稚拙之后 在滄桑之前 我希望有一天 我能有配得上苦難的清澈 與絕望相抗衡的堅(jiān)韌...
    取名真麻煩orz閱讀 81評(píng)論 0 0
  • 某君在火車站問站長:“請(qǐng)問特快列車開出了沒有床三?” “開出了,先生杨幼∑膊荆” “普通列車呢?” “8點(diǎn)半便過了站了差购。...
    梓毓爸閱讀 151評(píng)論 3 2