Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 设置BigDecimal的特定精度_Java_Bigdecimal_Floating Point Precision - Fatal编程技术网

Java 设置BigDecimal的特定精度

Java 设置BigDecimal的特定精度,java,bigdecimal,floating-point-precision,Java,Bigdecimal,Floating Point Precision,我有一个需要使用大十进制表示lat/lon的。目前我将lat/lon作为双精度,并将其转换为BigDecimal,但我只需要使用大约12位精度。我还没有弄明白如何设置它。有人能帮我做这个吗?你可以用 问题的题目是关于精确性的。区分尺度和精度。刻度是小数位数。您可以将精度视为的数量,也称为有效数字 Clojure中的一些示例 (.比例尺0.00123M);5. (.精度0.00123M);3. (在Clojure中,M指定了一个BigDecimal文本。如果您愿意,可以将Clojure翻译成Ja

我有一个需要使用大十进制表示lat/lon的。目前我将lat/lon作为双精度,并将其转换为BigDecimal,但我只需要使用大约12位精度。我还没有弄明白如何设置它。有人能帮我做这个吗?

你可以用


问题的题目是关于精确性的。区分尺度和精度。刻度是小数位数。您可以将精度视为的数量,也称为有效数字

Clojure中的一些示例

(.比例尺0.00123M);5.
(.精度0.00123M);3.
(在Clojure中,
M
指定了一个BigDecimal文本。如果您愿意,可以将Clojure翻译成Java,但我发现它比Java更紧凑!)

您可以轻松地增加比例:

(.setScale 0.00123M 7);0.0012300M
但不能用完全相同的方法减小比例:

(.setScale 0.00123m3);算术异常舍入是必需的
您还需要通过舍入模式:

(.setScale 0.00123m3大十进制/四舍五入半偶数);
; 注意:BigDecimal希望您使用MathContext舍入
; 常数,但我现在手头没有。
因此,很容易改变比例。但是精确性呢?这并不像你希望的那么容易

很容易降低精度:

(.round 3.14159M(java.math.MathContext.3));3.14米
但如何提高精度并不明显:

(.round 3.14159M(java.math.MathContext.7));3.14159米(意外)
对于持怀疑态度的人来说,这不仅仅是没有显示尾随零的问题:

(.precision(.round 3.14159M(java.math.MathContext.7));6.
; (同上,仍属意外)
FWIW,Clojure小心处理尾随的零,并将显示它们:

4.0000M;4.000米
(.精度4.0000M);5.
回到正轨上。。。您可以尝试使用构造函数,但它不会将精度设置为高于您指定的位数:

(BigDecimal.“3”(java.math.MathContext.5));3米
(BigDecimal.“3.1”(java.math.MathContext.5));3.1米
因此,没有快速改变精度的方法。我在写这个问题和我正在做的一个项目时,花了很多时间来解决这个问题。我认为这充其量是一个疯狂的API,最坏的是一个bug。人。真的吗

因此,据我所知,如果要更改精度,需要执行以下步骤:

  • 查找当前精度
  • 查找当前比例
  • 计算比例变化
  • 设定新的尺度
  • 以下步骤,如Clojure代码:

    (def x 0.000691M);输入号码
    (def p'1);期望精度
    (def s'(+(.scale x)p'((.precision x)));理想的新规模
    (.setScale x s'大十进制/四舍五入半偶数)
    ; 0.0007M
    
    我知道,这是很多步骤只是为了改变精度

    为什么BigDecimal还没有提供呢?我忽略了什么吗

     BigDecimal decPrec = (BigDecimal)yo.get("Avg");
     decPrec = decPrec.setScale(5, RoundingMode.CEILING);
     String value= String.valueOf(decPrec);
    
    通过这种方式,您可以设置
    BigDecimal
    的特定精度

    decPrec的值为
    1.5726903423607562595809913132345426
    四舍五入为
    1.57267

    请尝试此代码

        Integer perc = 5;
        BigDecimal spread = BigDecimal.ZERO; 
        BigDecimal perc = spread.setScale(perc,BigDecimal.ROUND_HALF_UP);
        System.out.println(perc);
    

    结果:0.00000

    您是否尝试过给构造函数一个MathContext?如果我没看错的话,您说的是小数点,而不是浮点精度。至少接受的答案将产生12位小数,而不是12位精度。Duh。回顾我得到的错误,它说四舍五入是必要的。我只做了。设置刻度(12)。一旦我确认它有效,我会按回答的那样做。谢谢。我不知道为什么它不像铸造那样只使用默认的舍入方法,我只见过舍入一半。这相当迂腐关于
    BigDecimal.round(新的MathContext(精度,RoundingModel.round_-HALF_偶数))
    呢?@PaŭloEbermann你是在问还是在建议?你试过了吗?介意分享我在回答中所列举的例子的详细结果吗?如果是这样的话,我认为这需要一个单独的答案。对于任何像我这样不懂Clojure的人,我认为这里显示的解决方案是
    x.setScale(x.scale()+p-x.precision(),RoundingMode.HALF_UP)
    ,其中
    x
    是要舍入的
    BigDecimal
    p
    是您要保留的有效数字的数量。这对我有用,但如果我错了,请纠正我@Nateowami我喜欢你的解决方案,但不幸的是,它似乎不能在角落的情况下正常工作,例如99.99。您的语句(3个有效数字)将其转换为100.0,而它应该仅为100。有一个额外的有效数字,因为99到99的“溢出”100@Kr1z说得好。猜测这是这个答案的局限性。我能想到的唯一一件事就是事后检查并再次取整数字是否有误。我认为它不可能第二次添加一个数字。
        Integer perc = 5;
        BigDecimal spread = BigDecimal.ZERO; 
        BigDecimal perc = spread.setScale(perc,BigDecimal.ROUND_HALF_UP);
        System.out.println(perc);