我需要确保我的所有十进制数字始终最多为15个字符(包括点),同时保持尽可能高的精度。因此,最多包含15个字符,包括“。”。科学表示法的“ E”和“-”。
我当时想的是对大数使用科学计数法,对小数使用四舍五入。
例如,对于1234567891234567.123456789,我将使用科学计数法,但是对于0.123456789123456789,我将对其进行四舍五入。
我正在寻找可以为我完成此工作的Java库,但找不到任何可以指定表示形式的字符总数的库。
感谢任何建议或指示。
编辑:更多的想法-通过使用24000E-18可以无损失地表示一个数字,例如0.000000000000024。例如,尽管0.123456789123424必须遭受一些损失,但这当然使得编写任何类型的简单分支算法变得更加困难。
EDIT2:我们用于传输数据的格式为字母数字,并将数据限制为总共15个字符。我必须编写代码来满足格式要求,以便可以在不触发格式错误的情况下传输数据,但同时仍要保持最大精度。
EDIT3:我正在用它来测试我的功能,但是到目前为止,在许多情况下,一切都失败了:
Random rnd = new Random();
double n = 100000 + rnd.nextDouble() * 900000;
String res;
double rangeMin = -123456789123456D;
double rangeMax = 123456789123456D;
String val;
for (int i=1;i<=1000;i++) {
n = rangeMin + (rangeMax - rangeMin) * rnd.nextDouble();
val = Double.toString(n);
res = shorteningFunction(val);
System.out.println(val + " " + val.length() + " " + res + " " + res.length());
}
参考方案
可以使用BigDecimal
,对于整数部分BigInteger
。
/**
* @param num number representation.
* @param max the maximal length the result should have.
* @return
*/
public static String truncateNumber(String num, int max) {
num = num.replaceFirst("\\.0*$", "");
BigDecimal x = new BigDecimal(num);
// Large numbers - integral part
String bigI = x.toBigInteger().toString();
if (bigI.length() > max) {
int expon10 = bigI.length() - max - 1; // - 1 for E
// Digits after E:
if (expon10 == 0) {
++expon10;
} else {
for (int p = expon10; p > 0; ++p) {
++expon10;
p /= 10;
}
}
x = x.movePointLeft(expon10);
String plain = x.toPlainString().substring(0, max - 1 - expon10);
return plain + "E" + expon10;
}
// Tiny numbers - 0.000 (as E-1 already requires 3 positions)
String reprP = x.toPlainString();
if (reprP.startsWith("-0.00")) {
return truncateNumber(num.substring(1), max - 1);
} else if (reprP.startsWith("0.00")) {
String reprE = x.toEngineeringString(); // Does most work.
int epos = reprE.indexOf('E');
String mantissa = reprE.substring(0, epos);
String exp = reprE.substring(epos);
return mantissa.substring(0, Math.min(epos, max - exp.length())) + exp;
}
// Normal range - assumed in format 123.456, integral part in range
String simple = x.toPlainString();
if (simple.length() > max) {
simple = simple.substring(0, max).replaceFirst("\\.0*$", "");
}
return simple;
}
可以更好地编写以\.0*
结尾的子字符串,尤其是toPlainString之类的重复使用。太小的max
也是有害的。
是否以科学/工程表示法给出num
也是一个未知数。
我有一个字符串4.9.14_05_29_16_21,我只需要获取4.9。数字各不相同,所以我不能简单地获得此char数组的前三个元素。我必须找到最正确的.并将其子字符串化直到那里。我来自Python,因此我将展示Python的实现方法。def foobar(some_string): location = some_string.rfind('.&…
Java string.hashcode()提供不同的值 - java我已经在这个问题上停留了几个小时。我已经注释掉所有代码,认为这与数组超出范围有关,但是这种情况仍在发生。我正在尝试使用扫描仪从文件中读取输入,存储数据并稍后使用哈希码获取该数据。但是哈希值不断变化。public static void main(String[] args) { //only prior code is to access data char…
在Java中使用新关键字和直接赋值的字符串 - javaString s="hi"; String s1=new String("hi"); 从内存角度看,s和s1存储在哪里?无论是在堆内存还是堆栈中。s指向“ hi”,而s1指向hi存在的内存位置?请帮忙? 参考方案 考虑以下 String s = "hi"; String s1 = new Strin…
Java-搜索字符串数组中的字符串 - java在Java中,我们是否有任何方法可以发现特定字符串是字符串数组的一部分。我可以避免出现一个循环。例如String [] array = {"AA","BB","CC" }; string x = "BB" 我想要一个if (some condition to tell wheth…
如何转义将成为字符串一部分的斜线? - java我很难找到一种方法来逃避这些引用,String key = StringUtils.substringBetween(html, "class=\"category_keyword\"", ">"); 特别是这部分:"class=\"category_keyword…