我最近在处理数字,我遇到了一种情况,我想将双精度值设置为 6 位或 4 位,具体取决于存储在数据库中的值。
例如,如果在数据库中将精度设置为 4 位,则输出必须如下所示,
10.0000
.
我尝试DecimalFormat
使用 string ##.####
,但每次都使用符号很烦人。
有没有更好的方法,说如下:
Double value = 10.0;
value.setPrecision(4);
我最近在处理数字,我遇到了一种情况,我想将双精度值设置为 6 位或 4 位,具体取决于存储在数据库中的值。
例如,如果在数据库中将精度设置为 4 位,则输出必须如下所示,
10.0000
.
我尝试DecimalFormat
使用 string ##.####
,但每次都使用符号很烦人。
有没有更好的方法,说如下:
Double value = 10.0;
value.setPrecision(4);
您可以为此尝试BigDecimal
Double toBeTruncated = new Double("3.5789055");
Double truncatedDouble = BigDecimal.valueOf(toBeTruncated)
.setScale(3, RoundingMode.HALF_UP)
.doubleValue();
您不能将双精度(或双精度)设置为指定的小数位数,因为浮点值没有小数位数。它们有二进制数字。
您必须通过BigDecimal
或转换为十进制基数DecimalFormat
,具体取决于您以后要对该值执行的操作。
另请参阅我对这个问题的回答,以反驳不可避免的 *100/100 答案。
这是一个简单的方法:
String formato = String.format("%.2f");
它将精度设置为 2 位。
如果您只想打印,请以这种方式使用它:
System.out.printf("%.2f",123.234);
为双精度值设置精度DecimalFormat
是一种很好的技术。例如,要使用此类导入java.text.DecimalFormat
并创建它的对象
double no=12.786;
DecimalFormat dec = new DecimalFormat("#0.00");
System.out.println(dec.format(no));
所以它会在小数点后打印两位数,它会打印 12.79
这对我有用:
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);
}
这是实现结果的一种有效方法,但需要注意两点。
在此处查看示例测试用例。
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);
与数学运算相比,字符串操作的计算成本很高。在我的测试中,与字符串操作相比,以下代码(没有 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;
}
和的精度由它们的大小和double
IEEE浮点类型的实现方式固定。float
另一方面,输出中的小数位数是格式问题。你是正确的,一遍又一遍地输入相同的常量是一个坏主意。您应该改为声明一个字符串常量,并使用它的符号表示。
private static final String DBL_FMT = "##.####";
使用符号表示可以让您更改使用常量的所有位置的精度,而无需搜索代码。
BigDecimal value = new BigDecimal(10.0000);
value.setScale(4);
为了扩展@EJP,处理双打时的“精度”概念非常令人担忧。正如https://stackoverflow.com/a/3730040/390153中所讨论的,无论精度如何,您甚至都不能将 0.1 表示为双精度数,出于同样的原因,您不能以有限的精度表示以 10 为底的 1/3。
您需要考虑您要解决的问题,并考虑:
a)我应该首先使用双打吗?如果精度是一个相关概念,那么使用双精度可能是一个错误。
b)如果双打是合适的,我所说的精度是什么意思?如果你只是在谈论显示,将逻辑包装在一个显示函数中,你只需要在一个地方处理它;IE。应用 DRY 原则。
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;
}
也许这种方法可以帮助您精确计算双精度值。
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;
}