2013-10-04 2 views
0

Я пытаюсь создать структуру «BigDouble» в .NET. Номер BigDouble имеет интегральную часть BigInteger и двойную дробную часть.Умножение двух значений BigDouble

Внедрение дополнений и подделок прост, но как я могу умножить/делить? Проблема в том, что я не мог найти способ умножить BigInteger с двойным. Что мне делать?

Помните: мне нужен точный пол и приблизительная дробная часть.

+0

Извините, но вы не сможете умножить BigInteger и double и получить точную целочисленную часть. У нас не всегда есть то, что мы хотим. –

+0

Вы можете «преобразовать» двойную в 2 ** x * (a/b), где x, a и b являются целыми числами соответствующего размера и исходят оттуда. –

+4

Я должен посоветовать вам, что это просто не очень хорошая идея. У вас, похоже, есть фундаментальное непонимание того, что такое двойник и как оно работает. Двойной представляет значение с гранулярностью, соответствующей его величине. Прикрепляя его к доле 1, вы просто отбрасываете компонент величины двойной. Поскольку ваша дробная часть всегда имеет заданную величину, вместо нее вместо нее используйте другое целочисленное значение (без знака). Репрезентативным значением будет значение, деленное на максимальное значение для этого целого. Это дает вам значения от 0 до 1, как требуется для вашего дробного компонента. –

ответ

0

A double имеет фиксированное количество бит мантиассы и показатель степени. Согласно спецификациям IEEE, mantiassa будет иметь 52 бит, а bis до десятичной точки будет опущен, но всегда будет 1. Таким образом, у вас есть как минимум 53 бит информации за десятичной точкой. Если вам повезет, а дробная часть мала, вы можете иметь большее разрешение, но маловероятно, если неотъемлемая часть отлична от нуля.

Поэтому одно решение будет умножать дробную часть на 2 и округлить ее до целого числа. Затем вы можете вычислять с помощью этих масштабированных значений, использовать их для формирования больших целых чисел и масштабирования после этого. Если вы хотите избежать потери данных любой ценой, вам нужно будет определить показатель числа double и соответствующим образом масштабировать. Я знаю некоторые функции на других языках, например Math.getExponent в Java или ilogb в C. Я бы предположил, что в .net есть что-то подобное, но я не знаю об этом.

Но все это наблюдение говорит мне (и может также сказать вам), что double, вероятно, не является удобным способом хранения дробной части. Сила double является ее плавающей точкой: вы можете хранить как очень маленькие, так и чрезвычайно большие значения, используя изменяющиеся показатели. Однако в вашем приложении вы будете хранить значения из диапазона [0,1] с примерно равной вероятностью (или, как я полагаю). Таким образом, основная сила double не используется. Я думаю, вам может быть лучше использовать фиксированную точность на основе BigInteger. Я предлагаю использовать 64 бит после десятичной точки. Требования к хранилищу будут такими же, как и в вашем подходе, поскольку double занимает 64 бит. Но в большинстве случаев точность будет увеличена примерно на 11 бит, так как вы можете использовать все 64 бит для полезных цифр, а не только 53 в вашем подходе. И производительность будет намного лучше, так как вам не нужно конвертировать между форматами.

Смежные вопросы