Я пытаюсь воссоздать реализацию арифметического кодирования на Java, как описано в этой ссылке, в разделе «Арифметическое кодирование: как это работает»: ссылка
Я нахожусь в точке, где отдельным символам нужно присвоить диапазон вдоль линии вероятности. Однако у меня возникают некоторые проблемы с созданием правильных диапазонов. В моем коде, показанном ниже, это выполняется с помощью 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;
}
}