首页天道酬勤bigdecimal比较大于0,double转bigdecimal

bigdecimal比较大于0,double转bigdecimal

张世龙 05-06 11:09 129次浏览

【转载】原文链接: https://blog.csdn.net/lk force/article/details/81564927

以上结论:不要直接使用双精度变量作为构建BigDecimal的参数。

在线上有以下Java代码逻辑:

1、界面传来了JSON的字符串,里面有数字。 57.3。

2 )解析JSON,将该数字保存在一个float变量中。

3,将这个浮点变量代入BigDecimal对象。 使用BigDecimal双精度参数的结构:

新双精度。

4 .将此BigDecimal保存到MySQL数据库中。 字段类型为decimal (15,2 )。

这个代码逻辑在线运行了很长时间,但存储在数据库中的值为57.3也没问题。 但是,在今天的调试时,步骤3中存储在BigDecimal对象中的值为57.299999237060546875,而不是57.3,这显然导致了精度问题。

数据库最终保存正确的57.3是因为字段类型设置为两位小数,如果超过两位小数,则会进行四舍五入,因此得到了正确的结果。 和MySQL掩盖了这个精度问题一样。

我总觉得这是个漏洞,所以研究了相关知识。

首先是BigDecimal的双精度参数结构。 在官方JDK文档中,该结构描述如下:

公共二进制(双精度)。

translatesadoubleintoabigdecimalwhichistheexactdecimalrepresentationofthedouble’sbinaryfloating-point value.thescaleofthe

Notes:

theresultsofthisconstructorcanbesomewhatunpredictable.onemightassumethatwritingnewbigdecimal (0.1 ) )。 injavacreatesabigdecimalwhichisexactlyequalto 0.1 (anunscaledvalueof 1,with a scale of 1), utitisactuallyequalto 0.1000000000005115123125782702118340451015625.this is because 0.1 cannotberepresentedexactlyas asabinaryfractionofanyfinitelength, Thus,thevaluethatisbeingpassedintotheconstructorisnotexactlyequater

The String constructor,on the other hand,isperfectlypredictable : writingnewbigdecimal (“0.1”) createsabigdecimalwhichises asonewouldexpect.Thich itisgenerallyrecommendedthatthestringconstructorbeusedinpreferencetothisone。

whenadoublemustbeusedasasourceforabigdecimal,notethatthisconstructorprovidesanexactconversion; itdoesnotgivethesameresultasconvertingthedoubletoastringusingthedouble.tostring (double ) methodandthenusingthebigdecimal (

Parameters:

val-doublevaluetobeconvertedtobigdecimal。

Throws:

numberformatexception-ifvalisinfiniteornan。

翻译后大致如下:

1,BigDecimal(doubleval )结构,以double为参数构建bigdecimal对象。

2但是这个结构不太可靠。 (unpredictable )、bigdecimal )、0.1 )你可能认为完全等于0.1,你认为你想的是什么? 不,bigdecimal(0.1 )这个商品实际上等于0.100000000005111511231257827021183404541015625。 因为准确地说0.1本身不能说是double。 (实际上,0.1不能表示任意定长二进制。

3,bigdecimal(stringval )结构可靠。 bigdecimal )“0.1”完全等于0.1。 推荐这个结构。

4 )如果你必须使用double变量构建BigDecimal,没关系。 我们亲切地提供静态的方法value of (双精度)。 此方法与newdecimal ) double.tostring (double ) )具有相同的效果。

简言之,最好使用String类型作为参数,或者使用静态方法valueOf(double ),而不是直接将double变量作为参数。 我写了一个例子:

publicstaticvoidmain (字符串[ ] args ) { float a=57.3f; bigdecimaldecimala=new bigdecimal (a; system.out.println(decimala; 双精度b=57.3; bigdecimaldecimalb=new bigdecimal (b; system.out.println(decimalb; 双精度c=57.3; bigdecimaldecimalc=new bigdecimal (double.tostring (c ); system.out.println(decimalc; 双精度d=57.3; bigdecimaldecimald=bigdecimal.value of (d; system.out.println(decimald; }输出结果:

57.299999237060546875

57.299999999999971578290569595999256515029296875

57.3

57.3

今后请尽量按照官方推荐的那样做。 否则,不知道什么时候又会给自己挖洞。

double 转BigDecimal 丢失精度问题解决