如何在不失去android精度的情况下对结果进行舍入

时间:2011-08-11 06:38:09

标签: java rounding precision bigdecimal

我正在android中构建一个基本的计算器功能。 但是当结果显示在TextView中时,我对于对数字进行四舍五入没有什么问题。

我正在进行123456789 * 123456789的乘法并得到我无法在TextView中容纳的结果。 在Android内置计算器中执行时,上述操作的实际结果为1.5241E16。 任何人都可以告诉我,如何在我的计算器应用程序中实现此结果? 以下是我想要做的事情的小片段:

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

Plz帮助我实现1.5241E16的结果1 ... 9 * 1 .... 9

2 个答案:

答案 0 :(得分:1)

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

因此,如果我得到的数字是1234567890,我想将其显示为3位小数。我会做1234567890/10 ^ 9(因为在第一个数字后有9位数字)然后我会简单地在char 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

答案 1 :(得分:0)

舍入问题的一个解决方案

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