我有一个XSD,要求我在经纬度上使用BigDecimal。目前我的经纬度是double类型,我将其转换为BigDecimal,但我只需要使用约12位精度。我一直没有找到如何设置精度的方法。有人能帮助我吗?
我有一个XSD,要求我在经纬度上使用BigDecimal。目前我的经纬度是double类型,我将其转换为BigDecimal,但我只需要使用约12位精度。我一直没有找到如何设置精度的方法。有人能帮助我吗?
你可以使用setScale()方法。
double d = ...
BigDecimal db = new BigDecimal(d).setScale(12, BigDecimal.ROUND_HALF_UP);
(.scale 0.00123M) ; 5
(.precision 0.00123M) ; 3
M
表示BigDecimal字面值。如果您愿意,可以将Clojure代码转换为Java代码,但我发现它比Java更紧凑!(.setScale 0.00123M 7) ; 0.0012300M
但是你无法以完全相同的方式减小比例尺:
(.setScale 0.00123M 3) ; ArithmeticException Rounding necessary
您还需要传递一个舍入模式:
(.setScale 0.00123M 3 BigDecimal/ROUND_HALF_EVEN) ;
; Note: BigDecimal would prefer that you use the MathContext rounding
; constants, but I don't have them at my fingertips right now.
因此,更改比例很容易。但是精度呢?这并不像你希望的那么容易!
减少精度很容易:
(.round 3.14159M (java.math.MathContext. 3)) ; 3.14M
但如何提高精度并不明显:
(.round 3.14159M (java.math.MathContext. 7)) ; 3.14159M (unexpected)
对于怀疑者来说,这不仅仅是尾随零未显示的问题:
(.precision (.round 3.14159M (java.math.MathContext. 7))) ; 6
; (same as above, still unexpected)
顺便提一下,Clojure在处理尾随零时非常小心,会显示它们:
4.0000M ; 4.0000M
(.precision 4.0000M) ; 5
回到正题...您可以尝试使用BigDecimal构造函数,但它不会将精度设置得比您指定的数字高:
(BigDecimal. "3" (java.math.MathContext. 5)) ; 3M
(BigDecimal. "3.1" (java.math.MathContext. 5)) ; 3.1M
(def x 0.000691M) ; the input number
(def p' 1) ; desired precision
(def s' (+ (.scale x) p' (- (.precision x)))) ; desired new scale
(.setScale x s' BigDecimal/ROUND_HALF_EVEN)
; 0.0007M
BigDecimal.round(new MathContext(precision, RoundingModel.ROUND_HALF_EVEN))
怎么样? - Paŭlo Ebermannx.setScale(x.scale() + p - x.precision(), RoundingMode.HALF_UP)
,其中x
是您想要舍入的BigDecimal
,而p
是您想要保留的有效数字位数。对我来说它起作用了,但如果我错了,请纠正我! - Nateowami BigDecimal decPrec = (BigDecimal)yo.get("Avg");
decPrec = decPrec.setScale(5, RoundingMode.CEILING);
String value= String.valueOf(decPrec);
通过这种方式,您可以设置 BigDecimal
的特定精度。
decPrec 的值为 1.5726903423607562595809913132345426
,四舍五入后为 1.57267
。
在处理BigDecimal时,精度和比例是两个非常重要的术语,您可以尝试单独设置它们或同时设置它们:
1. Precision
BigDecimal.ZERO.round(new MathContext(30, RoundingMode.FLOOR)); or
BigDecimal.valueOf(5878).round(new MathContext(10, RoundingMode.FLOOR));
2. Scale
BigDecimal.valueOf(5878).setScale(7, RoundingMode.CEILING);
3. Both precision and scale
BigDecimal.ONE.round(new MathContext(30, RoundingMode.FLOOR)).setScale(7, RoundingMode.FLOOR);
BigDecimal 的精度和刻度是相互排斥的概念。引用 https://dev59.com/-VsW5IYBdhLWcg3wDzvs#35435775:
精度:有效数字总位数
刻度:小数点右侧的数字位数
要更改 BigDecimal 的精度,请使用 BigDecimal.round(new MathContext(precision, roundingMode))
。
要更改 BigDecimal 的刻度,请使用 BigDecimal.setScale(scale, roundingMode)
。
尝试这段代码...
Integer perc = 5;
BigDecimal spread = BigDecimal.ZERO;
BigDecimal perc = spread.setScale(perc,BigDecimal.ROUND_HALF_UP);
System.out.println(perc);
结果:0.00000