【问题标题】:How to round up the result without losing its precision in android如何在不丢失 android 精度的情况下对结果进行四舍五入
【发布时间】:2011-08-11 06:38:09
【问题描述】:

我正在 android 中构建一个基本的计算器功能。 但是当结果显示在 TextView 中时,我在四舍五入时遇到了小问题。

我正在做 123456789 * 123456789 的乘法运算,得到的结果在我的 TextView 中无法容纳。 此外,在 Android 内置计算器中执行上述操作的实际结果为 1.5241E16。 谁能告诉我如何在我的计算器应用程序中实现这个结果? 下面是关于我正在尝试做的事情的小sn-p:

public static double round(double unrounded, int precision, int roundingMode)
    {
        BigDecimal bd = new BigDecimal(unrounded);
        BigDecimal rounded = bd.setScale(precision, roundingMode);
        return rounded.doubleValue();
    }

    num = num * Double.parseDouble(txtCalc.getText().toString());
    num = round(num, 3, BigDecimal.ROUND_HALF_UP); //where 3 is the precision of number

请帮我实现结果 1.5241E16 为 1...9 * 1....9

【问题讨论】:

  • 我很困惑,你得到了什么结果?科学记数法确实失去准确性。 1.5241E16 仅仅意味着答案大约是 1.5241*10,000,000,000,000,000,这意味着如果您可以决定要显示多少小数位,您可以将您的数字除以 10^X 并连接结果。
  • 是的,同样的,我也只想将结果四舍五入为 1.5241E16。
  • 我在下面的答案中添加了代码,可以提供您想要的结果。

标签: java rounding precision bigdecimal


【解决方案1】:

科学记数法确实失去准确性。 1.5241E16 仅表示答案大约是 1.5241*10,000,000,000,000,000,这意味着如果您可以决定要显示多少个小数位,您可以将数字除以 10^X 并连接结果。

因此,如果我得到的数字是 1234567890,并且我想将其显示到小数点后 3 位。我会做 1234567890 / 10^9 (因为第一个数字后面有 9 位数字),然后我会简单地将字符 5 之后的所有内容连接起来(整数位为 1 位,点为 1 位,然后是小数点后 3 位)。如果要舍入最后一个小数位,只需检查位置 6 的数字是否大于或等于 5,然后将最后一个数字加 1。

这里给出了你想要的结果。

double num1 = 123456789L;
double num2 = 123456789L;
String result = num1*num2+"";
if(result.contains("E")){ //if result is in scientific notation
    //take the first 6 characters only and part containing the E, drop everything else.
    result = result.substring(0, 6) + result.substring(result.indexOf("E"));
}
System.out.println("Result is = " + result);

我的 Groovy shell 的输出:

结果是 = 1.5241E16

【讨论】:

  • :但是如何知道用户输入的位数呢?即在你的情况下它是 10^9。任何代码 sn-p 都会对我有所帮助,因为我对数学并不那么容易:)。谢谢阿里
  • 在上面的代码中,我只是在进行任何连接之前检查 E。您当然必须在其中进行更多检查,例如如果 result.indexOf("E") > 6 只有然后连接。否则,您的结果最多保留 4 位小数。
  • @阿里:谢谢,成功了!正是我想要的。它适用于范围内的所有类型的数字吗?
【解决方案2】:

舍入问题的一种解决方案

package com.test;

import java.math.BigDecimal;
import java.math.RoundingMode;

/**
 * @VinTech Blogs
 * @vintech2277.blogspot.com
 *
 */
public class SumSame 
{
    public static void main( String[] args )
    {
     String[] from= {"3.2571365449","4.87608977397","5.29831575733","1.5684579238"};
     BigDecimal[] fromBD = new BigDecimal[from.length];
     BigDecimal[] toBD = new BigDecimal[from.length];

     BigDecimal diff = new BigDecimal("0");
     int high = 0;
     int low = 0;

     for(int i=0;i0) if(fromBD[i].compareTo(fromBD[high]) > 0){
         high= i;
        }else if(fromBD[i].compareTo(fromBD[low]) < 0){
         low= i;
        }
      //set scale to 2 means 2 digits after decimal               
                // HALf_DOWN means 11.45 rounds to 11.4
                //HALF_UP means 11.45 rounds to 11.5
      toBD[i] = fromBD[i].setScale(2, RoundingMode.HALF_DOWN);
      diff = diff.add(fromBD[i].subtract(toBD[i]));
     }    

     //We get the difference here and allocate the diffs to highest or lowest based
     //on diff value type
     if(diff.doubleValue() > 0.0){
      toBD[low]=toBD[low].add(diff).setScale(2,RoundingMode.HALF_DOWN);
     }else if(diff.doubleValue() < 0.0){
      toBD[high]=toBD[high].add(diff).setScale(2,RoundingMode.HALF_DOWN);
     }   

     for (BigDecimal bigDecimal : toBD) {
   System.out.println("val is "+bigDecimal);
  }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-01
    • 1970-01-01
    • 2010-09-06
    • 2011-12-12
    • 1970-01-01
    相关资源
    最近更新 更多