我想在C中定义一个新类型,它应该取值:
此外,它应该只需要5位内存。 (最小尺寸)
答案 0 :(得分:0)
原始问题已从5位更改为4,但范围0..16 需要5位,正如有几个人所评论的那样。
您无法使用小于char
的存储类型。你的问题来自算术和位操作(例如移位),因为你必须屏蔽不属于你的类型的位,这必须用(内联)函数或宏来完成。
然而,签名 5位类型会带来更大的问题。您无法在没有符号扩展到高位的情况下进行乘法运算和其他运算。如果结果为负,则必须截断这些位,因为它们位于5位字段之外。另一方面,如果您不截断它们,则使用的是8位字段而不是5位字段。
除此之外,您还无法打印任何已签名的值或将其投放到char
或int
,而无需先对其进行签名扩展。所以你毕竟不会真正使用5位类型。
#include <stdio.h>
#define MASK5 0x1F
#define MASKX 0xF0
typedef unsigned char u5; // unsigned 5-bit type
typedef char s5; // signed 5-bit type
char extend5 (char num) {
if (num & MASKX)
num |= MASKX;
return num;
}
s5 mul_s5 (s5 arg1, s5 arg2) {
return (s5)((extend5(arg1) * extend5(arg2)) & MASK5);
}
u5 mul_u5 (u5 arg1, u5 arg2) {
return (arg1 * arg2) & MASK5;
}
int main(void)
{
// simple example
printf ("%2u * %2u = %2u\n", 2, 3, (unsigned)mul_u5((u5)2, (u5)3));
// overflow example is truncated
printf ("%2u * %2u = %2u\n",12,23, (unsigned)mul_u5((u5)12, (u5)23));
// signed example without extending product
printf ("%2d * %2d = %2d\n",-2, 3, (int)mul_s5((s5)-2, (s5)3));
// signed example with sign extension
printf ("%2d * %2d = %2d\n",-2, 3, (int)extend5(mul_s5((s5)-2, (s5)3)));
return 0;
}
节目输出
2 * 3 = 6
12 * 23 = 20
-2 * 3 = 26
-2 * 3 = -6