如何将二进制数转换为带符号的十进制

时间:2019-07-27 07:18:55

标签: c

假设我有这个二进制数“ 1011”,并且我想将其转换为带符号的十进制,因此它是“ -3”而不是“ 11”。我该怎么办?

2 个答案:

答案 0 :(得分:0)

十进制,二进制,十六进制,八进制...仅是字符串表示形式的问题;不管我们使用什么基数,整数值(例如存储在int变量中)都保持不变。

例如

int a=33;   // understood as decimal representation by the compiler
int b=0x21; // understood as hexadecimal representation by the compiler
int c=041;  // understood as octal representation by the compiler
int d='!';  // understood as ASCII representation by the compiler
if((a==b)&&(a==c)&&(a==d))
{
  printf("this condition is always true!\n");
}

然后,我们可以从问题中假设"1011"是以2为基数的4位有符号整数的字符串表示形式,并且我们想产生另一个包含以base表示的相同值的表示形式的字符串10。

假设我们依靠广泛使用的two's complement表示形式,这是一个分步示例(可能存在一些更有效的方法来执行相同的操作)。

#include <stdio.h>
#include <string.h>
#include <assert.h>

int
read_bin_value(const char *bin_str)
{
  unsigned int result=0;
  const int bin_len=8*(int)sizeof(result);
  const int str_len=(int)strlen(bin_str);
  assert(str_len&&(str_len<=bin_len));
  // extract bits from bin_str
  for(int i=0; i<str_len; ++i)
  {
    const unsigned int bit=(bin_str[i]!='0'); // assume '1' if not '0'
    result|=(bit<<(str_len-1-i)); // place bit
  }
  // extend sign bit
  const unsigned int sign_bit=(bin_str[0]!='0');
  for(int i=str_len; i<bin_len; ++i)
  {
    result|=(sign_bit<<i);
  }
  // interpret as signed value
  return (int)result;
}

int
main(void)
{
  const char *bin_str[]={"1011", "0011", "0", "1", "01", NULL};
  for(int i=0; bin_str[i]; ++i)
  {
    char dec_str[20];
    snprintf(dec_str, sizeof(dec_str), "%d", read_bin_value(bin_str[i]));
    printf("%s --> %s\n", bin_str[i], dec_str);
  }
  return 0;
}

请注意,根据二进制补码,-3(基数10)的二进制表示形式不是"1011"(我想您应该认为有符号整数只是带符号位的无符号整数,但不是情况)。

答案 1 :(得分:0)

您必须确定要使用多少位表示并将输入作为字符串。

#include<stdio.h>
#include<string.h>
char numberAsAString[65];
int wordSize;
int binToSignedInt(char* numberAsAString,int wordSize)
{
    int value=0,multi=1,i,upto=1; //"upto" means we will stop calculating the value before 1st element...as the 0th element is containing sign bit and it is not a part of the value
    if(wordSize>strlen(numberAsAString))upto=0; //But if the word size is larger than the signed bit is assumed to be zero and we are taking the whole input as the value
    for(i=strlen(numberAsAString)-1;i>=upto;i--)
    {
        if(numberAsAString[i]=='1') //simple bin to dec conversion
        {
            value=value+multi;
        }
        multi=multi*2;
    }
    if(upto==0)return value; //If allowed number of bits representation was larger then the number was positive...as 0 is assumed at the beginning of the representation
    //otherwise
    if(numberAsAString[0]=='1')return -value; //If sign bit is 1 the value is negative
    return value; //The value is positive if the signed bit is not one (or is 0)
}
int main()
{
    printf("Enter number: "); //Enter the number as a sting
    scanf("%s",numberAsAString);
    printf("Enter word size: "); //Enter how many bits representation you want to use
    scanf("%d",&wordSize);
    if(wordSize<strlen(numberAsAString)) //If the number is larger than the allowed bits representation than considering the input as an invalid input
    {
        printf("Invalid Input\n");
        return 0;
    }
    printf("Value in signed integer form: %d\n",binToSignedInt(numberAsAString,wordSize)); //Signed integer output
    return 0;
}