补码⼀位乘法的c语⾔代码,定点数乘法运算:Booth算法(补
码⼀位乘法)C实现...
⽂章⽬录综述定点数的乘法运算Booth算法分析Booth算法的C实现
综述
在计算机中参与运算的机器数有两⼤类:⽆符号数和有符号数。
下⾯主要讲解有符号数:
在机器中,数的“正”、“负”号是⽆法识别的,有符号数⽤“0”表⽰正,⽤“1”表⽰负号,从⽽将符号数值化,并通常约定⼆进制数的最⾼位是符号位,即符号位放在有效数字的前⾯,组成有符号数。
有符号数的机器表⽰有原码、补码、反码和移码。
根据⼩数点的位置是否固定,在计算机中的有两种数据格式:定点表⽰和浮点表⽰。接下来我们将介绍的算法都是定点表⽰。
有关浮点数的内存存储及介绍请参考我的另⼀篇博⽂:
《浮点数在内存中的存储⽅式与运算陷阱》
定点表⽰即约定机器数中的⼩数点位置是固定不变的,⼩数点不再使⽤ “ . ” 表⽰,⽽是约定它的位置。理论上,⼩数点位置固定在哪⼀位都是可以的,但在计算机中通常采⽤两种简单的约定
将⼩数点的位置固定在数据的最⾼位之前,⼀般称为定点⼩数
将⼩数点的位置固定在数据的最⾼位之后,⼀般称为定点整数
定点⼩数是纯⼩数,约定⼩数点位置在符号位之后、有效数值部分最⾼位之前。
定点整数是纯整数,约定⼩数点位置在符号位有效数值部分最低位之后。
本⽂将介绍定点数的乘法运算。
定点数的乘法运算
在计算机中,乘法运算由累加和右移操作实现。根据机器数的不同,可分为
原码⼀位乘法
补码⼀位乘法
原码⼀位乘法的规则⽐补码⼀位乘法简单。我们下⾯主要介绍补码⼀位乘法(Booth)算法。
Booth算法分析
这是⼀种有符号数的乘法,采⽤相加和相减操作计算补码数据的乘积。
设 [X]补 = Xs.X1X2···Xn, [Y]补 = Ys.Y1Y2···Yn,则运算规则如下:
符号位参与运算,运算的数均以补码表⽰
被乘数⼀般取双符号位参与运算,部分积取双符号位,初值为0,乘数可取单符号位
乘数末尾增设附加位Yn+1,且初值为0
根据(Yn,Yn+1)的值来确定操作,具体见下表
移位按照补码右移规则进⾏
按照上述算法进⾏ n+1 步操作,但 n + 1 步不再移位(共进⾏ n + 1 次累加和 n次右移),仅根据Yn 与 Yn+1 的⽐较结果做相应的运算。
接下来我们分析⼀个实例:
设机器字长为5位(含⼀位符号位,n = 4),x = -0.1101,y = 0.1101,采⽤Booth算法求解 x · y。
Booth算法的C实现
通过上述分析,我们通过C语⾔来实现Booth算法。
问题描述:使⽤纯C实现Booth算法,不允许调⽤除输⼊输出外的其他功能库函数。
问题分析:
我们需要完成下述功能:
输⼊x、y,计算出 [X]补、[-X]补、 [Y]补将X改为双符号位数
部分积取双符号位,初值为0
分割乘数,获取(Yn,Yn+1)的值
根据(Yn,Yn+1)的值执⾏相应操作
完整设计如下:
/**
* Copyright: Copyright(c) 2019
* Created on 26/4/2019
* Author : ZYZMZM
* Version 1.0
* Title : Booth Algorithm
**/
#include
/* 存储被乘数 x 的补码 */
char xCom[20] = { 0 };
/* 存储 -x 的补码 */
char mxCom[20] = { 0 };
/* 存储乘数 y 的补码 */
char yCom[20] = { 0 };
/
小数的原码* 存储乘数 y 末位增加 0 */
char multiNum[20] = { 0 };
/* 存储部分积的初值 */
char multiSrc[20] = { 0 };
/* 计算字符串长度 */
int length(char* ch)
{
int len = 0;
while (*ch != NULL)
{
++len;
++ch;
}
return len;
}
/* 拷贝字符串 */
char* copy(char* dest, const char* src)
{
char* tmp = dest;
while (*dest++ = *src++) {}
return tmp;
}
/
* 字符串⽐较 */
int compare(const char* dest, const char* src)
{
int tmp = 0;
while (!(tmp = *dest - *src) && *dest && *src)
{
dest++;
src++;
}
if (tmp > 0) { return 1; }
else if (tmp < 0) { return -1; }
else { return 0; }
}
/* 字符串截取:截取从src中的begin下标到end下标的字符串,结果存储在res中 */ char* intercept(char* src, char *res, int begin, int end)
{
int i = begin;
int j = 0;
while (i <= end)
{
res[j] = src[i];
++j;
++i;
}
return res;
}
/* 右移 */
void mRight(char* src)
{
int len = length(src);
int i = len - 1;
/* 获取⼩数部分的起始位置 */
int num = 0;
char* p = src;
while (*p != '.')
{
++num;
++p;
}
++num;
/* 将⼩数后的第⼀位空出,其余全部后移 */
for (; i >= num; --i)
{
src[i + 1] = src[i];
}
++i;
/* 根据正负进⾏添1 或 添0 */
if (src[0] == '1')
{
src[i] = '1';
}
else
{
src[i] = '0';
}
}
/
* 浮点数加法 */
void Add(char* lhsstr, char *rhsstr, char *result) {
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论