单独的分配short int b=0xc000;
已经定义了实现(视频:ISO/IEC 9899:2018 6.3.1.3 p. 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
临时变量来完成其余部分。
假设输入仅限于unsigned short int
(unsigned
因为0xc000
) 的功能,并且所有类型都必须是有符号类型,但输出除外:
#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);
}
为了保持礼貌,作业的定义相当不明确,但由于我不知道是你的错,还是老师的错,还是变焦连接不好,所以我试着给你几个方向。如果不是预期的那样,您现在至少应该能够提出正确的问题。