“帶下劃線內容無效"
兩種不同方法的實現:
1:
/**
* 提供小數位四舍五入處理。
* @param v 需要四舍五入的數字
* @param scale 小數點后保留幾位
* @return 四舍五入后的結果
*/
public static double round(double v,int scale){
String temp="#,##0.";
for (int i=0;i<scale ;i++ )
{
temp+="0";
}
return Double.valueOf(new java.text.DecimalFormat(temp).format(v));
}
2:數學方法
public static double round2(double d, int scale) {
long temp=1;
for (int i=scale; i>;0; i--) {
temp*=10;
}
d*=temp;
long dl=Math.round(d);
return (double)(dl)/temp;
}
鑒于網友的的指出,我重新認真研究了一下四舍五入,最終給出正確解法如下:
import java.math.BigDecimal;
import java.text.DecimalFormat;
/**
* 本例通過對網上幾種取四舍五入的研究,進行了一一測試。最終通過實驗和理論得出round4為唯一正確的算法。
* 2008/10/13
*
* @author jamezhan
*
*/
public class RoundTest {
public static double round1(double v, int scale) {
if (scale < 0)
return v;
String temp = "#####0.";
for (int i = 0; i < scale; i++) {
temp += "0";
}
return Double.valueOf(new java.text.DecimalFormat(temp).format(v));
}
/**
* 該算法會出現中間運算后結果超過Double.MAX_VALUE,所以不推薦使用
* @param d
* @param scale
* @return
* @throws Exception
*/
public static double round2(double d, int scale) throws Exception {
if (scale < 0)
return d;
long temp = 1;
for (int i = scale; i > 0; i--) {
temp *= 10;
}
if (Math.abs(d * temp) > Double.MAX_VALUE)
throw new Exception("data is too big or too small");
d *= temp;
long dl = Math.round(d);
return (double) (dl) / temp;
}
public static double round3(double v, int scale) {
BigDecimal value = new BigDecimal(v);
float actualTax = value.setScale(scale, BigDecimal.ROUND_HALF_UP).floatValue();
return actualTax;
}
public static double round4(double v,int scale)
{
if(scale<0){
throw new IllegalArgumentException("The scale must be a positive integer or zero");
}
BigDecimal b = new BigDecimal(Double.toString(v));
BigDecimal one = new BigDecimal("1");
return b.divide(one,scale,BigDecimal.ROUND_HALF_UP).doubleValue();
}
public static void testRound1(double d, int scale) {
System.out.println("==========================");
System.out.println("data:"+ d + "; scale:"+scale);
double a = round1(d, scale);
System.out.println(a);
DecimalFormat df = new DecimalFormat();
System.out.println("formatted:"+df.format(a));
}
public static void testRound2(double d, int scale) {
try {
System.out.println("==========================");
System.out.println("data:"+ d + "; scale:"+scale);
double a = round2(d, scale);
System.out.println(a);
DecimalFormat df = new DecimalFormat();
System.out.println("formatted:"+df.format(a));
} catch (Exception e) {
System.err.println( e.getMessage() );
}
}
public static void testRound3(double d, int scale) {
try {
System.out.println("==========================");
System.out.println("data:"+ d + "; scale:"+scale);
double a = round3(d, scale);
System.out.println(a);
DecimalFormat df = new DecimalFormat();
System.out.println("formatted:"+df.format(a));
} catch (Exception e) {
System.err.println( e.getMessage() );
}
}
public static void testRound4(double d, int scale) {
try {
System.out.println("==========================");
System.out.println("data:"+ d + "; scale:"+scale);
double a = round4(d, scale);
System.out.println(a);
DecimalFormat df = new DecimalFormat();
System.out.println("formatted:"+df.format(a));
} catch (Exception e) {
System.err.println( e.getMessage() );
}
}
public static void main(String[] args) throws Exception {
System.out.println("****************************** Test round1 ******************************");
testRound1(Double.MAX_VALUE,2);
testRound1(1.264,2);
testRound1(-1.264,2);
testRound1(1.265,2);//wrong result
testRound1(-1.265,2);//wrong result
testRound1(1.266,2);
testRound1(-1.266,2);
testRound1(10224948.265,2);//wrong result
testRound1(-10224948.265,2);//wrong result
testRound1(-Double.MAX_VALUE, 2);
System.out.println("****************************** Test round2 ******************************");
testRound2(Double.MAX_VALUE,2);
testRound2(1.264,2);
testRound2(-1.264,2);
testRound2(1.265,2);//wrong result (java表示小數0.1的問題導致的 1.265表示為1.2599999904632568)
testRound2(-1.265,2);//wrong result (由于round算法是先加0.5再運算,所以d為負數時且最后一位小數為5時結果是不正確的)
testRound2(1.266,2);
testRound2(-1.266,2);
testRound2(10224948.265,2);
testRound2(-10224948.265,2);//wrong result
testRound2(-Double.MAX_VALUE, 2);
System.out.println("****************************** Test round3 ******************************");
testRound3(Double.MAX_VALUE,2);//wrong result
testRound3(1.264,2);
testRound3(-1.264,2);
testRound3(1.265,2);
testRound3(-1.265,2);
testRound3(1.266,2);
testRound3(-1.266,2);
testRound3(10224948.265,2);//wrong result
testRound3(-10224948.265,2);//wrong result
testRound3(-Double.MAX_VALUE, 2);//wrong result
System.out.println("****************************** Test round4 ******************************");
testRound4(Double.MAX_VALUE,2);
testRound4(1.264,2);
testRound4(-1.264,2);
testRound4(1.265,2);
testRound4(-1.265,2);
testRound4(1.266,2);
testRound4(-1.266,2);
testRound4(10224948.265,2);
testRound4(-10224948.265,2);
testRound4(-Double.MAX_VALUE, 2);
}
}