我想在Java中截断浮点数,直到两个第一个非零十进制数字。例如,0.000134
到0.00013
或11.00401
到11.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)
答案 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();
}