【问题标题】:How can I return an unsigned integer as a binary value in C?如何在 C 中将无符号整数作为二进制值返回?
【发布时间】:2023-03-25 15:43:01
【问题描述】:

更具体地说,我需要创建一个函数 float_16(unsigned sign, unsigned exp, unsigned frac),它返回一个给定符号、指数和小数值的数字的 bit16 表示(bit16 是 typedef 无符号整数)作为无符号整数。

我有以下序言:

int main(int argc, const char * argv[]) {

    typedef unsigned int bit16;
    bit16 a;
    a = 0xABCD; // 1010 1011 1100 1101 in binary = 43981

    printf("Sign is: %d",extractSign(a));
    printf(" ");
    printf("Exponent is: %d",extractExp(a));
    printf(" ");
    printf("Fraction is: %d",extractFrac(a));
    …
}

在我的主程序中,这些值由单独的 C 文件中的函数检索:

int extractSign(bit16 x) //significant bit
{
    return (x >> 15) & 0x0001; // 0x0001 is mask for 1 bit
}

int extractExp(bit16 x) // 7 bits
{
    return (x >> 8) & 0x007F; // 0x007F is mask for 7 bits
}

int extractFrac(bit16 x) // 8 bit fraction field
{
    return x & 0x00FF; // 0x00FF is mask for 8 bits
}

我如何能够使用这些值来满足这里的要求?

【问题讨论】:

  • 为什么需要符号位,如果它是无符号的?另外,不清楚你在问什么。
  • 要提取您右移和 AND 的位。要反转该过程,您只需左移和 OR。
  • @user3386109 当数字是十进制格式时,我该如何反转它?
  • 我假设您正在尝试实现float_16 函数,其原型在问题的第一行中给出。 sign 参数将是 0 或 1,exp 参数将是 0 到 127 之间的数字,frac 将是 0 到 255 之间的数字。不涉及十进制格式,除非用户以字符串形式提供数字。而且您的问题中没有提到您需要处理用户输入。
  • 看看HERE。它为您提供了使用已有的符号、exp 和分数所需的一切。

标签: c bit-manipulation bitwise-operators bit 16-bit


【解决方案1】:

您可以使用union

#include <stdio.h>

typedef unsigned short bit16; // On my computer, sizeof (int) == 4, while sizeof (short) == 2

union floating_point
{
    bit16 a;
    struct
    {
        unsigned frac : 8;
        unsigned exp : 7;
        unsigned sign : 1;
    } guts;
};

bit16 float_16 (unsigned sign, unsigned exp, unsigned frac);
unsigned extractSign (bit16 a);
unsigned extractExp (bit16 a);
unsigned extractFrac (bit16 a);

int main(int argc, const char * argv[])
{
    bit16 a = 0xABCD;
    printf("%d\n",a == float_16(extractSign(a),extractExp(a),extractFrac(a)));
    printf("Sign is: %u\n",extractSign(a));
    printf("Exponent is: %u\n",extractExp(a));
    printf("Fraction is: %u\n",extractFrac(a));
    return 0;
}

bit16 float_16 (unsigned sign, unsigned exp, unsigned frac)
{
    union floating_point value;
    value.guts.sign=sign;
    value.guts.exp=exp;
    value.guts.frac=frac;
    return value.a;
}

unsigned extractSign (bit16 a)
{
    union floating_point value;
    value.a=a;
    return value.guts.sign;
}

unsigned extractExp (bit16 a)
{
    union floating_point value;
    value.a=a;
    return value.guts.exp;
}

unsigned extractFrac (bit16 a)
{
    union floating_point value;
    value.a=a;
    return value.guts.frac;
}

【讨论】:

  • 当您确切知道编译器如何在内存中实现它们的布局时,您可以使用位域的联合。这是一个完整的依赖编译器的解决方案。
  • @LuisColorado 据我所知,这是一种未定义的行为,但得到了广泛的支持。
  • 我知道,但因此容易出现 U.B.
猜你喜欢
  • 2017-09-12
  • 2020-02-27
  • 1970-01-01
  • 1970-01-01
  • 2016-07-22
  • 2019-02-23
  • 2018-04-29
  • 1970-01-01
  • 2019-02-02
相关资源
最近更新 更多