Java:如何设置双精度值?
我最近在处理数字,我有一种情况,我想根据数据库中存储的值来设置double值的精度,比如6位数或4位数。
例如,如果在数据库中的精度被设置为4位,那么输出必须看起来像,
10.0000
。
我尝试了DecimalFormat
并使用string##.####
,但每次都使用符号很烦人。
有没有更好的方法,比如下面的说法:
Double value = 10.0; value.setPrecision(4);
您不能将double(或Double)的精度设置为指定的小数位数,因为浮点值没有十进制数字。 他们有二进制数字。
您必须通过BigDecimal
或DecimalFormat
将其转换为小数基数,具体取决于您稍后要使用的值。
另请参阅我对这个问题的回答 ,以驳斥不可避免的* 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);
double
和float
的精度由它们的大小和IEEE浮点types的实现方式决定。
另一方面,输出中的小数位数是格式化的问题。 你是正确的,反复input相同的常量是一个坏主意。 您应该声明一个string常量,并使用其符号表示forms。
private static final String DBL_FMT = "##.####";
使用符号表示可以让您在所有使用常量的地方更改精度,而无需search代码。
这里有一个有效的方法来达到两个警告的结果。
- 将精度限制为“最大”N位(不固定为N位)。
- 向下舍入数字(不舍入到最近)。
在这里看到示例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; }