Имам куп числа с плаваща запетая (удвоявания на Java), повечето от които са много близки до 1, и трябва да ги умножа заедно като част от по-голямо изчисление. Трябва да правя това много.
Проблемът е, че докато Java удвоява няма проблем с число като:
0.0000000000000000000000000000000001 (1.0E-34)
те не могат да представляват нещо като:
1.0000000000000000000000000000000001
Вследствие на това бързо губя прецизност (лимитът изглежда е около 1.000000000000001 за двойките на Java).
Обмислях просто да съхраня числата с извадено 1, така че например 1,0001 ще бъде съхранено като 0,0001 - но проблемът е, че за да ги умножа отново заедно, трябва да добавя 1 и в този момент губя точност.
За да се справя с това, бих могъл да използвам BigDecimal, за да извърша изчислението (преобразуване в BigDecimal, добавяне на 1.0, след това умножение) и след това обратно преобразуване в двойни след това, но имам сериозни притеснения относно последиците от това за производителността.
Може ли някой да види начин за това, който избягва използването на BigDecimal?
Редактиране за яснота: Това е за широкомащабен филтър за сътрудничество, който използва алгоритъм за оптимизиране на градиентно спускане. Точността е проблем, тъй като често филтърът за сътрудничество работи с много малки числа (като вероятността човек да кликне върху реклама за продукт, която може да бъде 1 на 1000 или 1 на 10 000).
Скоростта е проблем, тъй като филтърът за сътрудничество трябва да бъде обучен върху десетки милиони точки от данни, ако не и повече.