使用按位运算符在C中模拟浮点乘法 [英] Simulating Floating Point Multiplication in C using Bitwise Operators

查看:138
本文介绍了使用按位运算符在C中模拟浮点乘法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我必须编写一个程序来模拟浮点乘法.对于此程序,我们假定单个精度浮点数存储在unsigned long a中.我只能使用以下运算符将a中存储的数字乘以2:<< >> | & ~ ^

I have to write a program that will simulate floating point multiplication. For this program, we assume that a single precision floating point number is stored in unsigned long a. I have to multiply the number stored in a by 2 using only the following operators: << >> | & ~ ^

我了解这些运算符的功能,但是我对如何执行此操作的逻辑感到困惑.任何帮助将不胜感激.

I understand the functions of these operators, but I'm confused on the logic of how to go about implementing this. Any help would be greatly appreciated.

推荐答案

只能使用以下运算符将a中存储的数字乘以2:<< >> | & 〜^

have to multiply the number stored in a by 2 using only the following operators: << >> | & ~ ^

由于我们给了无符号长整数以单精度点来模拟浮点值,因此我们应该处理所有可以模拟的东西. ref

since we are given an unsigned long to simulate a float value with a single point of precision, we're supposed to handle all that could be simulated. ref

首先让我们假设浮点数被编码为 binary32 并且unsigned是32位. C不需要这两个.

First let's us assume the float is encoded as binary32 and that unsigned is 32-bit. C does not require either of these.

首先隔离要处理float子组的指数:次正态,正态,无限和

First isolate the exponent to deal with the float sub-groups: sub-normal, normal, infinity and NAN.

下面是一些经过严格测试的代码-我待会儿回顾,现在将其视为伪代码模板.

Below is some lightly tested code - I'll review later, For now consider it a pseudo code template.

#define FLT_SIGN_MASK  0x80000000u
#define FLT_MANT_MASK  0x007FFFFFu
#define FLT_EXPO_MASK  0x7F800000u
#define FLT_EXPO_LESSTHAN_MAXLVAUE(e)   ((~(e)) & FLT_EXPO_MASK)
#define FLT_EXPO_MAX   FLT_EXPO_MASK
#define FLT_EXPO_LSBit 0x00800000u

unsigned increment_expo(unsigned a) {
  unsigned carry = FLT_EXPO_LSBit;
  do {
    unsigned sum = a ^ carry;
    carry = (a & carry) << 1;
    a = sum;
  } while (carry);
  return a;
}

unsigned float_x2_simulated(unsigned x) {
  unsigned expo = x & FLT_EXPO_MASK;
  if (expo) { // x is a normal, infinity or NaN
    if (FLT_EXPO_LESSTHAN_MAXLVAUE(expo)) { // x is a normal
      expo = increment_expo(expo);  // Double the number
      if (FLT_EXPO_LESSTHAN_MAXLVAUE(expo)) { // no overflow
        return (x & (FLT_SIGN_MASK | FLT_MANT_MASK)) | expo;
      }
      return (x & FLT_SIGN_MASK) | FLT_EXPO_MAX;
    }
    // x is an infinity or NaN
    return x;
  }
  // x is a sub-normal
  unsigned m = (x & FLT_MANT_MASK) << 1;  // Double the value
  if (m & FLT_SIGN_MASK) {
    // Doubling caused sub-normal to become normal
    // Special code not needed here and the "carry" becomes the 1 exponent.
  }
  return (x & FLT_SIGN_MASK) | m;
}

这篇关于使用按位运算符在C中模拟浮点乘法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆