Java:如何设置双精度值?

我最近在处理数字,我有一种情况,我想根据数据库中存储的值来设置double值的精度,比如6位数或4位数。

例如,如果在数据库中的精度被设置为4位,那么输出必须看起来像,

10.0000

我尝试了DecimalFormat并使用string##.#### ,但每次都使用符号很烦人。

有没有更好的方法,比如下面的说法:

 Double value = 10.0; value.setPrecision(4); 

您不能将double(或Double)的精度设置为指定的小数位数,因为浮点值没有十进制数字。 他们有二进制数字。

您必须通过BigDecimalDecimalFormat将其转换为小数基数,具体取决于您稍后要使用的值。

另请参阅我对这个问题的回答 ,以驳斥不可避免的* 100/100的答案。

您可以尝试BigDecimal用于此目的

 Double toBeTruncated = new Double("3.5789055"); Double truncatedDouble = BigDecimal.valueOf(toBeTruncated) .setScale(3, RoundingMode.HALF_UP) .doubleValue(); 

这是一个简单的方法来做到这一点。

 String formato = String.format("%.2f"); 

它设定的任何2位数的指示。

如果你只想打印它使用这种方式。

 System.out.printf("%.2f",123.234); 

doublefloat的精度由它们的大小和IEEE浮点types的实现方式决定。

另一方面,输出中的小数位数是格式化的问题。 你是正确的,反复input相同的常量是一个坏主意。 您应该声明一个string常量,并使用其符号表示forms。

 private static final String DBL_FMT = "##.####"; 

使用符号表示可以让您在所有使用常量的地方更改精度,而无需search代码。

这里有一个有效的方法来达到两个警告的结果。

  1. 将精度限制为“最大”N位(不固定为N位)。
  2. 向下舍入数字(不舍入到最近)。

在这里看到示例testing用例。

 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 

这是代码。 上面提到的两个警告可以很容易的解决,但是,速度对我来说比准确性更重要,所以我把它留在了这里。 string操作,如System.out.printf("%.2f",123.234); 与math运算相比在计算上是昂贵的。 在我的testing中,与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; } 

这对我工作:

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

为double值设置精度DecimalFormat是一种很好的技术。 要使用这个类,请导入java.text.DecimalFormat并创build它的对象

 double no=12.786; DecimalFormat dec = new DecimalFormat("#0.00"); System.out.println(dec.format(no)); 

所以它会在小数点后打印两位数字,在这里打印12.79

为了扩大@EJP,在处理双打时,“精确”的概念非常充实。 正如在https://stackoverflow.com/a/3730040/390153中所讨论的那样,无论精度如何,您甚至不能将0.1表示为double,因为基于同样的原因,您无法以有限精度表示基数10中的1/3。;

您需要考虑您尝试解决的问题,并考虑:

a)我应该首先使用双打; 如果精度是一个相关的概念,那么使用双打可能是一个错误。

b)如果双打合适,我的意思是什么? 如果你只是在讨论显示,把逻辑包装在显示function中,你只需要在一个地方处理它; 即。 应用DRY原则。

 BigDecimal value = new BigDecimal(10.0000); value.setScale(4); 

我看到顶部的答案:

 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,即精度丢失。

解决scheme要么使用BigDecimaltypes没有.doubleValue()方法来显示或在最终的答案后使用string格式

也许这种方法将帮助你精确的双重价值。

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