2016-07-15 41 views
1

我想截斷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家庭高級版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) 
+3

這看起來不像那些笨蛋。這裏的OP想要有一個動態的小數位數,即保留最多兩個第一個非零的十進制數字。 – Tunaki

+0

@copeg不重複。這就像Tunaki說的。我認爲從我給出的兩個例子中可以清楚地看出。 – devil0150

+1

「浮點」「十進制數字」這兩個短語不應出現在同一句子中。你應該使用'BigDecimal'。 –

回答

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(); 
} 
+0

剛剛測試過,而且速度較慢。 3703毫秒,而我的方式爲538毫秒,500k隨機浮動。 – devil0150

+1

@ devil0150'BigDecimal'並不意味着要快,它的意思是正確的。 –

+0

@ devil0150你能分享你的代碼嗎?我正在考慮一種算法,就像Compass的算法一樣,但計算量較小。爲了確保我們將蘋果與蘋果進行比較,請分享您的代碼,將您產生隨機數的時間和方法分解出來。另外,讓我們知道您的機器/ JVM規格。 – mohsenmadi

相關問題