Я пытаюсь вручную реализовать умножение между двойным и 128-битным целым числом, которое я создал сам, используя два улонга.
Мое понимание таково:
1. Разложить двойное на его значение и и показатель. Обеспечение значимости и нормализовано .
2. Умножьте значение и мое мнение128. Это даст мне 256-битное число.
3. Сдвиньте мое 256-битное число на экспоненту, извлеченную из двойного.
4. Если значение превышает 128 бит, то я переполнен.
Мне кажется, что я невероятно близок, но что-то упускаю. Допустим, у меня есть следующий пример. Я храню uint128 со значением 2 ^ 127 и хочу умножить его на 8E-6.
uint128 myValue = new uint128(2^127);
double multiplier = 8E-6;
uint128 product = myValue * multiplier;
Реальное значение или правильный ответ 1361129467683753853853498429727072.845824
. Поэтому я хотел бы получить значение 1361129467683753853853498429727072
в качестве моего 128-разрядного целого числа.
Проблема в том, что моя реализация дает мне 1361129467683753792259819967610881
.
int exponent; // This value ends up being -69 for 8E-6
uint128 mantissa = GetMantissa(multiplier, out exponent); // This value ends up being 4722366482869645 after normalizing it.
uint256 productTemp = myValue * mantissa; // This value is something like 803469022129495101412490705402148357126451442021826560.
uint128 product = productTemp >> exponent. // this value is 1361129467683753792259819967610881
Я использую этот код из извлекает мантиссу и экспоненту из двойного в c#, чтобы получить мою мантиссу и экспоненту. Я могу использовать эти значения, чтобы правильно вернуть 8E-6 как двойное число.
Кто-нибудь знает, что я здесь ошибаюсь? Если я использую 0,8 вместо 8E-6, мои значения лучше.