使用有符号乘法器的无符号乘法 [英] Unsigned Multiplication using Signed Multiplier

查看:90
本文介绍了使用有符号乘法器的无符号乘法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被分配了一个使用有符号乘法器执行无符号乘法的任务.尽管进行了多次尝试,但我还是听不到.可以这样做吗?

I have been assigned with a task to perform unsigned multiplication using signed multiplier. Despite multiple attempts, I couldn't get it. Is it possible to do this?

代码:

#include <stdio.h>
int main()
{
    // Must be short int
    short int a=0x7fff;
    short int b=0xc000;
    unsigned int res1;
    signed int res2;
    
    //unsigned multiplier
    res1= (unsigned short int) a * (unsigned short int) b;
    
    //signed multiplier
    res2= (short int) a * (short int) b;

    printf("res1: 0x%x %d \n res2: 0x%x %d\n",res1,res1,res2,res2);
    return 0;
}

这是提供的代码.

当前输出:

res1: 0x5fff4000 1610563584 
res2: 0xe0004000 -536854528

预期输出:

res1: 0x5fff4000 1610563584 
res2: 0x5fff4000 1610563584 

工作代码:

#include<stdio.h>
#include<conio.h>
int main()
{
    short int a = 0x7fff;
    short int b = 0x3000;
    unsigned int unsignedRes;
    signed int signedRes;
    unsigned int ourRes;
    // Unsigned Multiplier
    unsignedRes = (unsigned short int) a * (unsigned short int) b;
    // Signed Multiplier
    signedRes = (short int) a * (short int) b;

    // Our Code using SIgned Multiplier
    ourRes = ((short int)a & ~(0xffffu << 16))*((short int)b & ~(0xffffu << 16));

    printf("Expected: 0x%x\nSigned: 0x%x\nResult: 0x%x",unsignedRes,signedRes,ourRes);
    getch();
    return 0;
}

推荐答案

仅赋值 short int b = 0xc000; 已被实现定义(视频:ISO/IEC 9899:2018 6.3.1.3第3页),并且需要分两个部分完成 b = b1 * 2 ^ 15 + b0 = 0x1 * 2 ^ 15 + 0x4000 (假设 SHRT_MAX + 1 == 32768 ).如果您同时在两个部分中都这样做,并且以这样的方式理解赋值,即结果是无符号数据类型,请执行 a * b ==(a1 * 2 ^ 15 + a0)*(b1 * 2 ^15 + b0),结果使用 unsigned int ret2 ,其余使用 signed int 临时变量.

The assignment short int b=0xc000; alone is already implementation defined (vid.: ISO/IEC 9899:2018 6.3.1.3 p. 3) and would need to be done in two parts b = b1 * 2^15 + b0 = 0x1*2^15 + 0x4000 (assuming SHRT_MAX + 1 == 32768 ). If you do both in two parts like that and understand the assignment in such a way that the result is an unsigned data type and do a*b == (a1 * 2^15 + a0) * (b1 * 2^15 + b0) by using unsigned int ret2 for the result and signed int temporary variables for the rest.

假定输入被限制为 unsigned short int (由于 0xc000 而由于 unsigned )的功能,并且所有类型都必须为签名类型,输出除外:

Assuming that the input is restricted to the capabilities of an unsigned short int (unsigned because of 0xc000) and that all types must be signed types with the exception of the output:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

int main(void)
{
   /*
      This whole thing has ben pulled apart for clarity and could (should!) be done
      in less lines of code.
      All implicit type conversions are made explicit.
      We also assume 2s complement (and a little bit more, to be honest).
    */

   /* 
       A and B limited to 0xffff to keep this code simple.
       If you want to get rid of these limits you need to count the bits
       of A and B and make sure that the sum does not exceed sizeof(int)*CHAR_BIT-1
    */
   signed int A = 0x7fff;
   signed int B = 0xc000;

   short int a0, a1;
   short int b0, b1;

   signed int shift = SHRT_MAX+1;

   unsigned int res1, res2;
   /* Additional temporary variables for legibility */
   signed int t0, t1, t2, t3;

   /* Check input range */
   if ((A > 0xffff) || (B > 0xffff)) {
      fprintf(stderr,"Input must not exceed 0xffff! A = 0x%x, B = 0x%x\n",A,B);
      exit(EXIT_FAILURE);
   }

   //unsigned multiplier
   res1 = (unsigned int)A * (unsigned int)B;

   //signed multiplier

   /* Compute  A*B == (a1 * shift + a0) * (b1 * shift + b0) */
   a0 = (short int)(A % shift);
   a1 = (short int)(A / shift);
   b0 = (short int)(B % shift);
   b1 = (short int)(B / shift);

   /*
      Multiply out for convenience:

      A*B == (a1 * 2^15 + a0) * (b1 * 2^15 + b0)
          ==  a1 * b1 *2^15 * 2^15
            + a0 * b1 * 2^15
            + a1 * b0 * 2^15
            + a0 * b0
    */
   /*
      Here a1 and b1 are either 0 (zero) or 1 (one) and (SHRT_MAX+1)^2 < INT_MAX
      so t0 cannot overflow.
      You should make use of that fact in production.
    */
   t0 = (signed int)a1 * (signed int)b1 * shift * shift; /* t0 in {0,shift^2} */
   t1 = (signed int)a0 * (signed int)b1 * shift; /* t1 in {0, a0 * shift} */
   t2 = (signed int)a1 * (signed int)b0 * shift; /* t2 in {0, b0 * shift} */
   t3 = (signed int)a0 * (signed int)b0; /* t3 can get larger than INT_MAX! */

   /* Cannot overflow because floor(sqrt(2^32-1)) = 0xffff and both A and B < 0xfff */
   res2 = (unsigned int)t0 + (unsigned int)t1 + (unsigned int)t2 + (unsigned int)t3;

   printf("res1: 0x%x %d\nres2: 0x%x %d\n",res1, res1, res2, res2);

   exit(EXIT_SUCCESS);
}

为了保持礼貌,作业的定义还不够明确,但是由于我不知道这是您的错,老师的错还是变焦连接不良,我试图为您提供一些指导.如果没想到,您现在至少应该能够提出正确的问题.

The assignment is rather under-defined, to keep it polite, but as I do not know if it is your fault, the teacher's fault or a bad zoom-connection I tried to give you a couple of directions. If it wasn't wat was expected you should at least be able to ask the right questions now.

这篇关于使用有符号乘法器的无符号乘法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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