我最近正在处理数字,我有一种情况,我希望将双精度值的精度设置为6位数或4位数,具体取决于数据库中存储的值。
例如,如果在数据库中精度设置为4位,则输出必须为
10.0000
。
我尝试使用DecimalFormat
并使用字符串##.####
,但每次使用符号都很烦人。
有没有更好的方法,如下所示:
Double value = 10.0;
value.setPrecision(4);
答案 0 :(得分:248)
您可以为此目的尝试BigDecimal
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
答案 1 :(得分:51)
这是一种简单的方法。
String formato = String.format("%.2f");
它将预设设置为2位数o。
如果你只想用这种方式打印它。
System.out.printf("%.2f",123.234);
答案 2 :(得分:50)
您不能将double(或Double)的精度设置为指定的十进制数字,因为浮点值没有十进制数字。它们有二进制数字。
您必须通过BigDecimal
或DecimalFormat
转换为十进制基数,具体取决于您稍后要对该值执行的操作。
另请参阅我对this question的回答,以反驳不可避免的* 100/100答案。
答案 3 :(得分:12)
设置双精度值serialize()
的精度是一种很好的技巧。要使用此类导入DecimalFormat
并创建它的对象,例如
java.text.DecimalFormat
因此它将在小数点后打印两位数字,它将打印12.79
答案 4 :(得分:8)
这对我有用:
public static void main(String[] s) {
Double d = Math.PI;
d = Double.parseDouble(String.format("%.3f", d)); // can be required precision
System.out.println(d);
}
答案 5 :(得分:3)
double
和float
的精确度取决于其大小和IEEE floating point types的实施方式。
另一方面,输出中的小数位数是格式化的问题。你是正确的,一遍又一遍地输入相同的常数是一个坏主意。你应该声明一个字符串常量,并使用它的符号表示。
private static final String DBL_FMT = "##.####";
使用符号表示可以让您在不使用代码搜索常量的情况下更改所有位置的精度。
答案 6 :(得分:3)
这是一个有效的方法,可以通过两个警告来实现结果。
请参阅此处的示例测试用例。
123.12345678 ==> 123.123
1.230000 ==> 1.23
1.1 ==> 1.1
1 ==> 1.0
0.000 ==> 0.0
0.00 ==> 0.0
0.4 ==> 0.4
0 ==> 0.0
1.4999 ==> 1.499
1.4995 ==> 1.499
1.4994 ==> 1.499
这是代码。我上面提到的两个警告很容易解决,然而,速度对我来说比准确性更重要,所以我把它留在这里。
与数学运算相比,像System.out.printf("%.2f",123.234);
这样的字符串操作在计算上是昂贵的。在我的测试中,与String操作相比,下面的代码(没有sysout)花费了1/30的时间。
public double limitPrecision(String dblAsString, int maxDigitsAfterDecimal) {
int multiplier = (int) Math.pow(10, maxDigitsAfterDecimal);
double truncated = (double) ((long) ((Double.parseDouble(dblAsString)) * multiplier)) / multiplier;
System.out.println(dblAsString + " ==> " + truncated);
return truncated;
}
答案 7 :(得分:2)
BigDecimal value = new BigDecimal(10.0000);
value.setScale(4);
答案 8 :(得分:1)
为了扩展@EJP,处理双打时'精确'的概念非常令人担忧。正如https://stackoverflow.com/a/3730040/390153中所讨论的那样,无论精度如何,你甚至都不能将0.1表示为双精度,因为同样的原因你不能用有限精度表示基数10的1/3。
您需要考虑您要解决的问题,并考虑:
a)我应该首先使用双打;如果精度是一个相关的概念,那么使用双精度可能是一个错误。
b)如果双打是合适的,我的精确度是什么意思?如果您只是谈论显示,请将逻辑包装在显示功能中,您只需要在一个地方处理它;即。应用DRY原则。
答案 9 :(得分:-1)
public static String setPrecision(String number, int decimal) {
double nbr = Double.valueOf(number);
int integer_Part = (int) nbr;
double float_Part = nbr - integer_Part;
int floating_point = (int) (Math.pow(10, decimal) * float_Part);
String final_nbr = String.valueOf(integer_Part) + "." + String.valueOf(floating_point);
return final_nbr;
}
答案 10 :(得分:-1)
也许这种方法可以帮助你预先设定双值。
double truncate(double number)
{
int integerPart = (int) number;
double fractionalPart = number - integerPart;
fractionalPart *= 100; //It is for upto two decimal values after point.
//You can increase the zeros to fulfill your needs.
int fractPart = (int) fractionalPart;
fractionalPart = (double) (integerPart) + (double) (fractPart)/100;
return fractionalPart;
}
此方法允许设置精度级别。
double truncate(double number, int precision)
{
double prec = Math.pow(10, precision);
int integerPart = (int) number;
double fractionalPart = number - integerPart;
fractionalPart *= prec;
int fractPart = (int) fractionalPart;
fractionalPart = (double) (integerPart) + (double) (fractPart)/prec;
return fractionalPart;
}
答案 11 :(得分:-2)
我在顶部看到了答案:
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
我认为这不是一个完美的答案,因为在许多情况下你拨打doubleValue()
时答案会改变。
示例:BigDecimal.valueOf(toBeTruncated).setScale(3, RoundingMode.HALF_UP)
的输出为12.500,
然后在.doubleValue()
之后,输出将为12.5,即精度丢失。
解决方案:使用BigDecimal
类型而不使用.doubleValue()
方法显示,或在最终答案后使用字符串格式。