我正在尝试重新创建算术编码的Java实现,如此链接中所述,在“算术编码:它如何工作”部分:link
我正处于需要沿概率线为各个符号分配范围的点。但是,我在创建正确的范围时遇到了一些问题。在下面显示的代码中,这是由setRanges()执行的。预期结果应为:
Character Ranges -
0.0 - 0.09999999999999999
A 0.1 - 0.19999999999999999
B 0.2 - 0.29999999999999999
E 0.3 - 0.39999999999999999
G 0.4 - 0.49999999999999999
I 0.5 - 0.59999999999999999
L 0.6 - 0.79999999999999999
S 0.8 - 0.89999999999999999
T 0.9 - 0.99999999999999999
我目前的输出是:
角色范围 -
0.0 - 0.09999999999999999
A 0.1 - 0.2
B 0.2 - 0.30000000000000004
E 0.30000000000000004 - 0.4
G 0.4 - 0.5
I 0.5 - 0.6
L 0.6 - 0.8
S 0.8 - 0.9
T 0.9 - 1.0
我不确定是否有更好的方法来编写我的方法setRanges(),或者这是否只是舍入错误的结果。
这是类Range,它只包含一个低和高浮点值:
public class Range {
private double low, high;
public Range(double low, double high) {
this.low = low;
this.high = high;
}
public String toString() {
return low + " - " + high;
}
}
方法:
import java.util.TreeMap;
public static TreeMap<Character, Range> setRanges(TreeMap<Character, Double> treeMap) {
TreeMap<Character, Range> rangeMap = new TreeMap<>();
double currentValue;
double previousValue = 0;
double runningTotal = 0;
for(Character key : treeMap.keySet()) {
currentValue = treeMap.get(key) + runningTotal;
rangeMap.put(key, new Range(previousValue, currentValue - 0.00000000000000001));
previousValue = currentValue;
runningTotal += treeMap.get(key);
}
return rangeMap;
}
}
答案 0 :(得分:2)
我认为你需要使用BigDecimal来达到这个精度。有128或没有roudning选项。见下文:
double first = 1d;
double second = 0.00000000000000001d;
System.out.println("Db --> " + (first - second));
BigDecimal firstBd = new BigDecimal(first);
BigDecimal secondBd = new BigDecimal(second);
BigDecimal resultBd = firstBd.subtract(secondBd);
System.out.println("32 --> " + resultBd.round(MathContext.DECIMAL32));
System.out.println("64 --> " + resultBd.round(MathContext.DECIMAL64));
System.out.println("128--> " + resultBd.round(MathContext.DECIMAL128));
System.out.println("Unl--> " + resultBd);
输出是:
Db - &gt; 1.0
32 - &gt; 1.000000
64 - &gt; 1.000000000000000
128 - &GT; 0.9999999999999999899999999999999993
Unl - &gt; 0.9999999999999999899999999999999992845757594537807549147194381507675227382936355979836662299931049346923828125