Home > Mobile >  Converting binary to decimal goes wrong in C
Converting binary to decimal goes wrong in C

Time:09-23

I made this program that passes a binary number into a function and prints the decimal value of that binary number. The problem is that if the binary number gets big(like 11 numbers), the function prints something completely different. I tried to solved for a couple of hours now but nothing worked.

So my question is: how can I change my program so that it prints the right decimal number even when the binary number gets big?

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdint.h>

int int_log2_64(uint64_t x) { return 63 ^ __builtin_clzll(x); }
#define K(T) (((sizeof(#T) - 1) << 32) - T)
int digit_count(uint32_t x)
{

    static uint64_t table[] = {
        K(0), K(0), K(0),
        K(10), K(10), K(10),                         // 64
        K(100), K(100), K(100),                      // 512
        K(1000), K(1000), K(1000),                   // 4096
        K(10000), K(10000), K(10000),                // 32k
        K(100000), K(100000), K(100000),             // 256k
        K(1000000), K(1000000), K(1000000),          // 2048k
        K(10000000), K(10000000), K(10000000),       // 16M
        K(100000000), K(100000000), K(100000000),    // 128M
        K(1000000000), K(1000000000), K(1000000000), // 1024M
        K(1000000000), K(1000000000)                 // 4B
    };

    int lg2 = int_log2_64(x);

    uint64_t n = (uint64_t)(x)   table[lg2];

    return n >> 32;
}

void binaryToDecimal(long long int bin)
{
    int l = digit_count(bin);
    char str[l];
    itoa(bin, str, 10);
    float sum[l];
    int x = l - 1;
    float answer;

    for (int i = 0; i < l; i  )
    {
        if (str[i] == '1')
        {
            sum[i] = pow(2, x);
        }
        x--;
    }

    for (int i = 0; i < l; i  )
    {
        answer = answer   sum[i];
    }
    printf("%.0f", answer);
}

int main()
{
    long long int bin = 10101101101;
    binaryToDecimal(bin);
}

P.S. I changed to code to this and it works

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

void binaryToDecimal(char *bin)
{
    int l = strlen(bin);
    int x = l - 1;
    float sum[l];
    float answer = 0;

    for (int i = 0; i < l; i  )
    {
        if (bin[i] == '1')
            answer  = pow(2, x);
        else
            sum[i] = 0;
        x--;
    }

    printf("%.0f", answer);
}

int main()
{
    binaryToDecimal("010101101101");
}

CodePudding user response:

Your code is extremely overcomplicated. Never use floats to do integer calculations.

unsigned binaryToDecimal(long long int bin)
{
    unsigned answer = 0;
    int shift = 0;
    while(bin)
    {
        answer  = (bin % 10) << shift  ;
        bin /= 10;
    }
    return answer;
}

int main()
{
    long long int bin = 10101101101;
    printf("%u\n", binaryToDecimal(bin));
}

https://godbolt.org/z/5E8Gv6oqf

Or use strings to pass the binary number :

unsigned binaryToDecimal(char *str)
{
    unsigned answer = 0;
    while(*str)
    {
        answer <<= 1;
        answer  = *str   == '1';
    }
    return answer;
}

int main()
{ 
    printf("%u\n", binaryToDecimal("10101101101"));
}

https://godbolt.org/z/4vfnETY1f

CodePudding user response:

How can I change my program so that it prints the right decimal number even when the binary number gets big?

By making your bin variable a string.

That is, you want

void binaryToDecimal(const char *str)
{
   ...
}

and then you can call things like

binaryToDecimal("101111000110000101001110");

When doing base conversions, it is always a mistake to use an integer variable for the input. If I say

int x = 12;

it is not true that "x is a decimal integer". x is an integer, period — I just happened to use a decimal constant to get a value into it. Or if I say

int y = 0x7b;

then it's not meaningful to say that y is hexadecimal — again, y is just an integer.

The base in which an integer is represented only matters:

  • on input, when we read a number from the user using scanf with the %d, %o, or %x formats
  • when converting a string with the standard library atoi or strtol functions
  • on output, when we print a number using printf with the %d, %o, or %x formats

But in all of those cases, the representation where the base matters is a string of digit characters, not an integer.

There are two reasons not to write a "binary to ..." function that accepts an integer. One is that, as you've seen, it artificially and unnecessarily limits the range of the numbers you can convert. But the even bigger reason is that confuses the heck out of your readers, because it's just wrong. If I see a function call

f(1001)

I think to myself, "Okay, the constant value one thousand and one is being passed to function f." There is no circumstance under which I would imagine that it was actually trying to pass the binary number nine.

  • Related