金钱最好使用long分单位但是仍然有人使用double应该怎么改造呢?

金钱最好使用long分单位但是仍然有人使用double应该怎么改造呢?


一:简介

Java中的简单浮点数类型float和double不能够进行运算,或者运算会丢失精度,不光是Java,在其它很多编程语言中也有这样的问题。在大多数情况下,计算的结果是准确的,float和double只能用来做科学计算或者是工程计算,在商业计算中我们要用 java.math.BigDecimal

<code> 
@

Test

public

void

testDouble

(

)

{ 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

); System.

out

.println(Math.round(

4.015

*

100

)/

100.0

); }/<code>

二:BigDecimal

BigDecimal有多种构造函数,常用的有2种,其中有一种不建议使用,就是double构造方式,建议使用String构造方式。

<code> 
 

public

BigDecimal

(String val)

;

public

BigDecimal

(

double

val)

;/<code>
<code>BigDecimal也定义了几个常用的值,

0

1

10

,静态的,可以通过类名直接引用BigDecimal.ZERO

public

static

final

BigDecimal ZERO = zeroThroughTen[

0

];

public

static

final

BigDecimal ONE = zeroThroughTen[

1

];

public

static

final

BigDecimal TEN = zeroThroughTen[

10

]; 三:工具类/<code>

由于构造方法要用String对应的构造方法,如果我们要做一个加法运算,需要先将两个浮点数转为String,然后构造成BigDecimal,在其中一个上调用add方法,传入另一个作为参数,然后把运算的结果(BigDecimal)再转换为浮点数。你能够忍受这么烦琐的过程吗?下面我们提供一个工具类来简化操作。

<code>

import

java.math.BigDecimal;

public

class

ArithUtil

{

private

static

final

int

DEF_DIV_SCALE =

10

;

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(); }

public

static

double

sub

(

double

v1,

double

v2)

{ BigDecimal b1 =

new

BigDecimal(Double.toString(v1)); BigDecimal b2 =

new

BigDecimal(Double.toString(v2));

return

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

public

static

double

mul

(

double

v1,

double

v2)

{ BigDecimal b1 =

new

BigDecimal(Double.toString(v1)); BigDecimal b2 =

new

BigDecimal(Double.toString(v2));

return

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

public

static

double

div

(

double

v1,

double

v2)

{

return

div(v1,v2,DEF_DIV_SCALE); }

public

static

double

div

(

double

v1,

double

v2,

int

scale)

{

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,BigDecimal.ROUND_HALF_UP).doubleValue(); }

public

static

double

round

(

double

v,

int

scale)

{

if

(scale<

0

){

throw

new

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(); } }/<code>

四:测试

<code>@

Test

public

void

testBigDecimal

(

)

{ BigDecimal price = BigDecimal.ZERO; BigDecimal amount =

new

BigDecimal(

"6.66"

); System.

out

.println(ArithUtil.

add

(

0.05

,

0.01

)); System.

out

.println(ArithUtil.sub(

1.0

,

0.42

)); System.

out

.println(ArithUtil.mul(

4.015

,

100

)); System.

out

.println(ArithUtil.div(

123.3

,

100

)); System.

out

.println(ArithUtil.round(

4.015

,

2

)); }/<code>

本号主要用于分享企业中常用的技术,更加侧重于实用,欢迎关注,便于浏览其它更多实用的历史文章。


分享到:


相關文章: