Ошибки при умножении чисел с помощью побитовых операторов - PullRequest
0 голосов
/ 08 февраля 2019

Я пытаюсь умножить два числа с плавающей запятой, используя побитовые операторы в формате IEEE-754.32-разрядное число составлено в виде знак - экспонента - мантисса .После умножения каждого числа результирующий ответ иногда будет правильным, но не всегда.

Я думаю, что это как-то связано с тем, что полученный ответ не находится в нормализованной форме (например, 1.1010101 * 2 * 1005).* 5 ), но я не знаю, как это исправить.

#include <csdtdio>

struct Real
{    
   int sign;
   long exponent;
   unsigned long fraction;
};

Real Multiply(Real Val1, Real Val2){
   Real answer;
   answer.fraction = left.fraction + right.fraction;
   answer.exponent = left.exponent  + right.exponent;
   answer.sign = left.sign ^ right.sign;
   return  answer;
}

1 Ответ

0 голосов
/ 08 февраля 2019

При умножении частей мантиссы нужно умножать вместе, не добавляйте

(- 1) sign1 × 2 exp1 × mantissa1 * (-1) sign2 × 2 exp2 × mantissa2
= (-1) sign1 + sign2 × 2 exp1 + exp2 × mantissa1 ×mantissa2

И вам не нужна отдельная переменная для возврата

Real Multiply(Real Val1, Real Val2){
   Val1.fraction *= Val2.fraction;
   Val1.exponent += Val2.exponent;
   Val1.sign ^= Val2.sign;
   return Val1;
}

После этих основных вещей вам все равно придется выполнить нормализацию, для которой вам нужно получитьполный результат, а не только младшие биты, как при обычном нерасширяющем умножении.Поэтому вы должны привести свою «дробь» (если вы используете IEEE-754, тогда правильный термин для нее - значимый и ) к более широкому типу.В зависимости от того, на какой платформе вы находитесь, вы можете иметь или не иметь тип в два раза больше, чем unsigned long.В этом случае лучше использовать типы фиксированной ширины, такие как int32_t, uint64_t.Вот и все подсказки, необходимые для этого

...