将float浮动到两个第一个非零十进制数字

时间:2016-07-15 18:50:26

标签: java floating-point

我想在Java中截断浮点数,直到两个第一个非零十进制数字。例如,0.0001340.0001311.0040111.0040

我能想到的唯一解决方法是去除整数部分,然后乘以10直到得到一个大于或等于10的数字。然后将原始浮点数截断为number of multiplications十进制数字。

但我可能不得不经常这样做,所以我正在寻找更快的解决方案。

我的测试代码:

public static String truncateTo2NonZero(double f) {
    int integral = (int)f;
    double decimal = f - integral;
    int digits = 0;

    while (decimal < 10) {
        decimal *= 10;
        digits++;
    }

    double ret = (int)decimal / Math.pow(10, digits);
    ret += integral;

    return Double.toString(ret);
}

public static void main(String args[]) {
    final int TESTS = 1000000;
    double[] floats = new double[TESTS];

    Random random = new Random();
    for (int i = 0; i < TESTS; ++i) {
        int zeros = random.nextInt(6) + 3; // divide by 10^zeros
        double digits = random.nextInt(100) + 100; // 3 last digits
        floats[i] = digits / Math.pow(10,zeros) + random.nextInt(20) + 1;
    }

    long startTime = System.nanoTime();
    for (int i = 0; i < TESTS; ++i)
        truncateTo2NonZero(floats[i]);
    long endTime = System.nanoTime();

    long duration = endTime - startTime;
    System.out.println(duration / 1000000); // in milliseconds
}

我使用的是Windows 7 Home Premium 64位。输出java -version

java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)

1 个答案:

答案 0 :(得分:1)

当你说你要“截断”时,这听起来就像一个显示格式。据说那些花车对此并不友好。 BigDecimals是。这应该是一个开始,当然需要错误检查。

static String roundToLastTwoDecimalDigits(float f) {
    // split whole number and decimals
    String[] floatParts = new BigDecimal(f).toPlainString().split("\\.");

    int wholeNumberPortion = Integer.parseInt(floatParts[0]);

    // count zeroes
    String decimalPortion = floatParts[1];
    int numDecimalPlaces = 0;
    while (decimalPortion.charAt(numDecimalPlaces) == '0')
        numDecimalPlaces++;

    // get 3 digits to round
    String toRound = decimalPortion.substring(numDecimalPlaces,
            numDecimalPlaces + 3);

    int decimalForRounding = Math.round(Float.parseFloat(toRound) / 10);

    StringBuilder sb = new StringBuilder();

    sb.append(wholeNumberPortion);
    sb.append(".");
    for (int i = 0; i < numDecimalPlaces; i++)
        sb.append("0");
    sb.append(decimalForRounding);

    return sb.toString();
}