问题描述
我需要以给定的精度将double转换为字符串。 String.format(%。3f,value)
(或DecimalFormat)做这项工作,但是基准测试表明,与不是非常快的> Double.toString 转换(在我的机器上转换1百万个数字约1-3秒)。
有没有更好的方法这个?$ / b
$ b
更新:基准测试结果
从0到1000000的随机数,结果是每毫秒的运算Java 1.7.0_45)
基准均值平均值错误单位
String_format 747.394 13.197 ops / ms
BigDecimal_toPlainString 1349.552 31.144 ops / ms
DecimalFormat_format 1890.917 28.886 ops / ms
Double_toString 3341.941 85.453 ops / ms
DoubleFormatUtil_formatDouble 7760.968 87.630 ops / ms
SO_User_格式14269.388 168.206 ops / ms
免责声明: 我只建议您使用此功能,如果速度是绝对的要求。
在我的机器上,以下可以在130ms内完成100万次转换: p>
private static final int POW10 [] = {1,10,100,1000,10000,100000,1000000};
public static String format(double val,int precision){
StringBuilder sb = new StringBuilder();
if(val sb.append(' - ');
val = -val;
}
int exp = POW10 [precision];
long lval =(long)(val * exp + 0.5);
sb.append(lval / exp).append('。');
long fval = lval%exp; (int p = precision - 1; p> 0&& fval< POW10 [p]; p--){
sb.append('0');
}
sb.append(fval);
return sb.toString();
}
所呈现的代码有几个缺点:它只能处理有限的范围双打
,它不处理NaN。前者可以通过扩展 POW10
数组来解决(但仅部分)。后者可以在代码中明确处理。
I need to convert double to string with given precision. String.format("%.3f", value)
(or DecimalFormat) does the job but benchmarks show that it slow even in comparison to not very fast Double.toString
conversion (about 1-3 seconds to convert 1 million numbers on my machine).
Are there any better way to do it?
UPDATE: Benchmarking results
Random numbers from 0 to 1000000, results are in operations per millisecond (Java 1.7.0_45)
Benchmark Mean Mean error Units
String_format 747.394 13.197 ops/ms
BigDecimal_toPlainString 1349.552 31.144 ops/ms
DecimalFormat_format 1890.917 28.886 ops/ms
Double_toString 3341.941 85.453 ops/ms
DoubleFormatUtil_formatDouble 7760.968 87.630 ops/ms
SO_User_format 14269.388 168.206 ops/ms
Disclaimer: I only recommend that you use this if speed is an absolute requirement.
On my machine, the following can do 1 million conversions in about 130ms:
private static final int POW10[] = {1, 10, 100, 1000, 10000, 100000, 1000000};
public static String format(double val, int precision) {
StringBuilder sb = new StringBuilder();
if (val < 0) {
sb.append('-');
val = -val;
}
int exp = POW10[precision];
long lval = (long)(val * exp + 0.5);
sb.append(lval / exp).append('.');
long fval = lval % exp;
for (int p = precision - 1; p > 0 && fval < POW10[p]; p--) {
sb.append('0');
}
sb.append(fval);
return sb.toString();
}
The code as presented has several shortcomings: it can only handle a limited range of doubles
, and it doesn't handle NaNs. The former can be addressed (but only partially) by extending the POW10
array. The latter can be explicitly handled in the code.
这篇关于具有给定精度的快速双字符串转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!