【发布时间】:2010-12-30 21:55:34
【问题描述】:
是否有可用于将数字截断为任意小数位数的 Java 库函数? 例如。
SomeLibrary.truncate(1.575, 2) = 1.57
谢谢
【问题讨论】:
标签: java
是否有可用于将数字截断为任意小数位数的 Java 库函数? 例如。
SomeLibrary.truncate(1.575, 2) = 1.57
谢谢
【问题讨论】:
标签: java
只需删除小数部分
public double trunk(double value){
return value - value % 1;
}
【讨论】:
在公共数学中有一个。查看http://commons.apache.org/math/apidocs/org/apache/commons/math/util/MathUtils.html:
public static double round(double x,
int scale)
它使用 BigDecimal 实现,并被重载以允许指定舍入方法,因此您可以使用它来截断,如下所示:
org.apache.commons.math.util.MathUtils.round(1.575, 2,
java.math.BigDecimal.ROUND_DOWN);
更新:
在上一个版本(Math3)中,这个方法在类Precision中。
org.apache.commons.math3.util.Precision.round(double x, int scale, int roundingMethod)
【讨论】:
这是一个简短的实现,比使用 BigDecimal 或 Math.pow 快很多倍
private static long TENS[] = new long[19];
static {
TENS[0] = 1;
for (int i = 1; i < TENS.length; i++) TENS[i] = 10 * TENS[i - 1];
}
public static double round(double v, int precision) {
assert precision >= 0 && precision < TENS.length;
double unscaled = v * TENS[precision];
if(unscaled < Long.MIN_VALUE || unscaled > Long.MAX_VALUE)
return v;
long unscaledLong = (long) (unscaled + (v < 0 ? -0.5 : 0.5));
return (double) unscaledLong / TENS[precision];
}
删除要品尝的断言。 ;)
【讨论】:
v 乘以(可能)10 的几个幂,这可能导致溢出。当然,双最大值约为 10^308,因此大多数人不会注意到这一点,但它是可能的,这是令人惊讶的行为(您不会期望舍入函数在提交有效值时会溢出)。跨度>
long 类型,该方法就会失败,这要快得多。如果要求足够的精度,即使参数 v 很小,这也可能非常快。
我只想添加到 ubuntudroid 的解决方案。 我试过了,它不会四舍五入,所以我不得不添加
df.setRoundingMode(RoundingMode.FLOOR);
让它工作。
【讨论】:
难以置信的是,还没有人提出这个问题,Java API 多年来一直有 DecimalFormat 用于这个确切的目的。
【讨论】:
使用这个简单的函数
double truncateDouble(double number, int numDigits) {
double result = number;
String arg = "" + number;
int idx = arg.indexOf('.');
if (idx!=-1) {
if (arg.length() > idx+numDigits) {
arg = arg.substring(0,idx+numDigits+1);
result = Double.parseDouble(arg);
}
}
return result ;
}
【讨论】:
像这样尝试BigDecimal的setScale:
public static double round(double d, int decimalPlace) {
BigDecimal bd = new BigDecimal(d);
bd = bd.setScale(decimalPlace, BigDecimal.ROUND_HALF_UP);
return bd.doubleValue();
}
【讨论】:
BigDecimal 已经有一个构造函数采用Double。 OP 似乎也不想将其四舍五入,而只是将其截断(下限)。
要做到 100% 可靠,您必须将参数作为字符串而不是浮点数传递。当以字符串形式给出时,代码很容易编写。原因在于
double x = 1.1;
并不意味着 x 实际上将计算为 1.1,仅计算为最接近的可精确表示的数字。
【讨论】:
其实这种东西很容易写:
public static double truncate(double value, int places) {
double multiplier = Math.pow(10, places);
return Math.floor(multiplier * value) / multiplier;
}
注意它是 Math.floor,因为 Math.round 不会被截断。
哦,这会返回一个 double,因为这是 Math 类中的大多数函数(如 Math.pow 和 Math.floor)返回的。
警告:双打不利于准确性。应首先考虑其中一种 BigDecimal 解决方案。
【讨论】:
创建了一个方法来做到这一点。
public double roundDouble(double d, int places) {
return Math.round(d * Math.pow(10, (double) places)) / Math.pow(10, (double)places);
}
【讨论】:
对于大多数数字,您将无法获得xxx.yyyy 的精确表示,除非您使用具有保证准确性的十进制类,例如BigDecimal。
【讨论】: