Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中是否有截断双精度的函数?_Java - Fatal编程技术网

java中是否有截断双精度的函数?

java中是否有截断双精度的函数?,java,Java,是否有Java库函数可用于将数字截断为任意小数位数? 比如说 SomeLibrary.truncate(1.575, 2) = 1.57 感谢大多数数字,除非使用精度有保证的十进制类,否则无法获得xxx.yyyy的精确表示形式,例如。要100%可靠地传递参数,必须将参数作为字符串而不是浮点数传递。当以字符串形式给出时,代码很容易编写。原因是, double x = 1.1; 并不意味着x实际上将计算为1.1,仅计算为最接近的可精确表示的数字。请尝试类似的设置比例: 创建了一个方法来执行此操作

是否有Java库函数可用于将数字截断为任意小数位数? 比如说

SomeLibrary.truncate(1.575, 2) = 1.57

感谢大多数数字,除非使用精度有保证的十进制类,否则无法获得xxx.yyyy的精确表示形式,例如。

要100%可靠地传递参数,必须将参数作为字符串而不是浮点数传递。当以字符串形式给出时,代码很容易编写。原因是,

double x = 1.1;
并不意味着x实际上将计算为1.1,仅计算为最接近的可精确表示的数字。

请尝试类似的设置比例:


创建了一个方法来执行此操作

public double roundDouble(double d, int places) {
    return Math.round(d * Math.pow(10, (double) places)) / Math.pow(10, (double)places);
}

在公共数学中有一个。退房:

它使用BigDecimal实现,并重载以允许指定舍入方法,因此您可以使用它来截断,如下所示:

org.apache.commons.math.util.MathUtils.round(1.575, 2, 
    java.math.BigDecimal.ROUND_DOWN);
更新:

在上一个版本(Math3)中,此方法位于类中。
org.apache.commons.math3.util.Precision.round(双x,int scale,int roundingMethod)

实际上,这种东西很容易写:

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解决方案。

令人难以置信的是,现在还没有人提出这个问题,Java API早就有了这个确切的目的。

下面是一个比使用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];
}
private static long TENS[]=new long[19];
静止的{
十[0]=1;
对于(inti=1;i=0&&precisionLong.MAX_值)
返回v;
长未标度长=(长)(未标度+(v<0-0.5:0.5));
返回(双精度)无标度长/十位数[精度];
}

删除要品尝的断言。;)

使用这个简单的函数

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

我只想补充一下ubuntudroid的解决方案。 我试过了,但它不能取整,所以我不得不补充

df.setRoundingMode(RoundingMode.FLOOR);

只需删除小数部分即可


公共双中继(双值){
返回值-值%1;
}

2注释:
BigDecimal
已经有一个构造函数使用了一个
Double
。OP似乎也不想把它四舍五入,只是为了截断它。实际上,BalusC是对的,我想截断这个值,你的回答给了我正确的方向,所以我接受了。你需要将舍入模式设置为BigDecimal。向下舍入,而不是向上舍入一半,以真正截断一个值。改进的版本使用正数和负数,而不是舍入。更基本的是,double没有小数位数,因为它们存储为二进制分数。或者使用BigDecimal,这是BigDecimal存在的原因之一。您仍然需要从字符串初始化它,而不是从double初始化。注意:pow是一个非常昂贵的函数。如果性能不是问题,请使用它。我喜欢这种简单明了的解决方案。@Mani(好吧,也适用于EJP所说的):我会注意到警告是有原因的。@Powerlord的目标是将双精度截断为任意小数位数,任何解决方案都应该做到这一点。这段代码没有也不能这样做,不是因为“精确性”,而是因为二进制分数和十进制分数是不可通约的。我看到的唯一问题是,您将参数
v
乘以(可能)10的几次幂,这可能会导致溢出。当然,double max值约为10^308,因此大多数人不会注意到这一点,但这是可能的,这是一种令人惊讶的行为(在提交有效值时,您不希望舍入函数出现溢出)。只要注意到未标度值超过
long
type,该方法就会失败,这要快得多。如果要求足够的精度,即使参数
v
很小,这也可能非常快。@UMad Ok,更改了应处理这两种情况的检查。round(9.625,2)返回9.63,根据问题,这是错误的。答案应该是9。62@PeterLawrey在第(9.62,2)轮到第9.61轮中,下降+0.5将不起作用。问题是double没有实际的小数点,您必须使用BigDecimal,或者应该添加额外的条件。对于给定的示例,代码如下所示:final DecimalFormat df=new DecimalFormat();df.setMaximumFractionDigits(2);df.格式(1.575);最后一个表达式返回一个字符串,该字符串必须转换回double。这将进行舍入,我认为问题是截断而不是舍入。的可能重复项
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 ;
}
df.setRoundingMode(RoundingMode.FLOOR);