-3

Hi I am pretty new to coding and I really need help. Basically I have a decimal value and I converted it to a binary value. Using this method

long decimalToBinary(long n) 
{
    int remainder; 
    long binary = 0, i = 1;

    while(n != 0) 
    {
        remainder = n%2;
        n = n/2;
        binary= binary + (remainder*i);
        i = i*10;
    }
    return binary;
}

And I want to give each character of the binary into it's own space inside an array. However, I can't seem to save digits from the return values in my string array. I think it has something to do with converting the long to string but I could be wrong! Here is what I have so far. I do not want to use sprintf(); I do not wish to print the value I just want the value stored inside it so that the if conditions can read it. Any help would be appreciated!

int decimalG = 24;
long binaryG = decimalToBinary(decimalG);
char myStringG[8] = {binaryG};
for( int i = 0; i<8; i++)
{
     if (myStringG[i] == '1' )
    {
     T1();
    }
    else 
    {
    T0();
 }
 }

In this case since the decimal is 24, the binary would be 11000 therefore it should execute the the function T1(); 2 times and T0() 6 times. But it doesn't do that and I can't seem to find the answer to store the saved values in the array.
*Ps the Itoa(); function is also not an option. Thanks in Advance! :)

AverageEh
  • 11
  • 2
  • 3
    Variables don't have a "decimal value" - unless you use a digital system with decimal memory cells. Unlikely, all modern computers are **binary**. And C does not support _methods_, only _functions_. – too honest for this site Aug 23 '16 at 23:52
  • Step back and have a look at what `decimalToBinary` actually does. It us nonsense. Just remove the whole body and `return n;`. No offence, but you really messed it up. It is not even really clear what you actually want to accomplish. As you are aware of `itoa` (lowercase!), you seem to have something different in mind. – too honest for this site Aug 24 '16 at 00:01
  • `char myStringG[8+1]; snprintf(myStringG, sizeof(myStringG), "%08ld", binaryG);` – BLUEPIXY Aug 24 '16 at 00:27
  • 2
    If your end goal is to run `T1()` and `T0()`, you don't really need to convert your decimal. Keep dividing the number by 2 and check for the remainder. Every time you get a remainder execute `T1()` otherwise execute `T0()`. – alvits Aug 24 '16 at 01:16
  • `char myStringG[8] = {binaryG};` initializes `myStringG[0] = binaryG;` and the remaining array elements to 0. – chux - Reinstate Monica Aug 24 '16 at 01:50
  • The only correct answer to this question is to use `itoa`. The OP is being ridiculous by asking people to reinvent the wheel. – DeftlyHacked Aug 24 '16 at 03:44

4 Answers4

1

As the post is tagged arm using malloc() might not be the best approach, although the simplest. If you insist on using arrays:

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

int decimalToBinary(long n, char out[], int len)
{
  long remainder;
  // C arrays are zero based
  len--;
  // TODO: check if the input is reasonable
  while (n != 0) {
    // pick a bit
    remainder = n % 2;
    // shift n one bit to the right
    // It is the same as n = n/2 but
    // is more telling of what you are doing:
    // shifting the whole thing to the right
    // and drop the least significant bit
    n >>= 1;
    // Check boundaries! Always!
    if (len < 0) {
      // return zero for "Fail"
      return 0;
    }
    // doing the following four things at once:
    // cast remainder to char
    // add the numerical value of the digit "0"
    // put it into the array at place len
    // decrement len
    out[len--] = (char) remainder + '0';
  }
  // return non-zero value for "All OK"
  return 1;
}

// I don't know what you do here, but it
// doesn't matter at all for this example
void T0()
{
  fputc('0', stdout);
}

void T1()
{
  fputc('1', stdout);
}

int main()
{
  // your input
  int decimalG = 24;
  // an array able to hold 8 (eight) elements of type char
  char myStringG[8];

  // call decimalToBinary with the number, the array and
  // the length of that array
  if (!decimalToBinary(decimalG, myStringG, 8)) {
    fprintf(stderr, "decimalToBinary failed\n");
    exit(EXIT_FAILURE);
  }
  // Print the whole array
  // How to get rid of the leading zeros is left to you
  for (int i = 0; i < 8; i++) {
    if (myStringG[i] == '1') {
      T1();
    } else {
      T0();
    }
  }
  // just for the optics
  fputc('\n', stdout);
  exit(EXIT_SUCCESS);
}

Computing the length needed is tricky, but if you know the size of long your Micro uses (8, 16, 32, or even 64 bit these days) you can take that as the maximum size for the array. Leaves the leading zeros but that should not be a problem, or is it?

deamentiaemundi
  • 5,502
  • 2
  • 12
  • 20
0

Use the itoa (integer-to-ascii) function.

http://www.cplusplus.com/reference/cstdlib/itoa/


EDIT: Correction:

Don't be an idiot, use the itoa (integer-to-ascii) function.

http://www.cplusplus.com/reference/cstdlib/itoa/


EDIT:

Maybe I wasn't clear enough. I saw the line that said:

*Ps the Itoa(); function is also not an option.

This is completely unreasonable. You want to reinvent the wheel, but you want someone else to do it? What do you possibly have against itoa? It's part of the standard. It will always exist, no matter what platform you're targeting or version of C that you're using.

DeftlyHacked
  • 405
  • 2
  • 9
0

To achieve your goal, you don't have to convert a decimal value to binary:

unsigned decimalG = 24; // Assumed positive, for negative values
                        // have implementation-defined representation
for (; decimalG; decimalG >>= 1) {
    if(decimalG & 1) {
        // Do something
    } else {
        // Do something else
    }
}

Or you can use a union, but I'm not sure whether this approach is well defined by the standard.


If you stick to writing decimalToBinary, note that you'll have to use an array:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

char *decimalToBinary(unsigned n);

int
main(void) {
    int decimalG = 15;
    char *binary = decimalToBinary(decimalG);
    puts(binary);
    free(binary);
}

char *
decimalToBinary(unsigned n) {
    // Don't forget to free() it after use!!!
    char *binary = malloc(sizeof(unsigned) * CHAR_BIT + 1);
    if(!binary) return 0;

    size_t i;
    for (i = 0; i < sizeof(unsigned) * CHAR_BIT; i++) {
        binary[i] = '0' + ((n >> i) & 1); // in reverse order
    }
    binary[i] = 0;

    return binary;
}
nalzok
  • 14,965
  • 21
  • 72
  • 139
0

I want to give each character of the binary into it's own space inside an array. However, I can't seem to save digits from the return values in my string array.

There are a number of ways to approach this, if I understand what you are asking. First, there is no need to actually store the results of the binary representation of your number in an array to call T1() or T0() based on the bit value of any given bit that makes up the number.

Take your example 24 (binary 11000). If I read your post correctly you state:

In this case since the decimal is 24, the binary would be 11000 therefore it should execute the the function T1() 2 times and T0() 6 times.

(I'm not sure where you get 6 times, it looks like you intended that T0() would be called 3 times)

If you have T0 and T1 defined, for example, to simply let you know when they are called, e.g.:

void T1 (void) { puts ("T1 called"); }
void T0 (void) { puts ("T0 called"); }

You can write a function (say named callt) to call T1 for each 1-bit and T0 for each 0-bit in a number simply as follows:

void callt (const unsigned long v)
{
    if (!v)  { putchar ('0'); return; };

    size_t sz = sizeof v * CHAR_BIT;
    unsigned long rem = 0;

    while (sz--)
        if ((rem = v >> sz)) {
            if (rem & 1) 
                T1(); 
            else 
                T0();
        }
}

So far example if you passed 24 to the function callt (24), the output would be:

$ ./bin/dec2bincallt
T1 called
T1 called
T0 called
T0 called
T0 called

(full example provided at the end of answer)

On the other hand, if you really do want to give each character of the binary into it's own space inside an array, then you would simply need to pass an array to capture the bit values (either the ASCII character representations for '0' and '1', or just 0 and 1) instead of calling T0 and T1 (you would also add a few lines to handle v=0 and also the nul-terminating character if you will use the array as a string) For example:

/** copy 'sz' bits of the binary representation of 'v' to 's'.
 *  returns pointer to 's', on success, empty string otherwise.
 *  's' must be adequately sized to hold 'sz + 1' bytes.
 */
char *bincpy (char *s, unsigned long v, unsigned sz)
{
    if (!s || !sz) {
        *s = 0;
        return s;
    }
    if (!v) {
        *s = '0';
        *(s + 1) = 0;
        return s;
    }
    unsigned i;

    for (i = 0; i < sz; i++)
        s[i] = (v >> (sz - 1 - i)) & 1 ? '1' : '0';
    s[sz] = 0;

    return s;
}

Let me know if you have any additional questions. Below are two example programs. Both take as their first argument the number to convert (or to process) as binary (default: 24 if no argument is given). The first simply calls T1 for each 1-bit and T0 for each 0-bit:

#include <stdio.h>
#include <stdlib.h>
#include <limits.h>         /* for CHAR_BIT */

void callt (const unsigned long v);
void T1 (void) { puts ("T1 called"); }
void T0 (void) { puts ("T0 called"); }

int main (int argc, char **argv) {

    unsigned long v = argc > 1 ? strtoul (argv[1], NULL, 10) : 24;

    callt (v);

    return 0;
}

void callt (const unsigned long v)
{
    if (!v)  { putchar ('0'); return; };

    size_t sz = sizeof v * CHAR_BIT;
    unsigned long rem = 0;

    while (sz--)
        if ((rem = v >> sz)) {
            if (rem & 1) T1(); else T0();
        }
}

Example Use/Output

$ ./bin/dec2bincallt
T1 called
T1 called
T0 called
T0 called
T0 called

$ ./bin/dec2bincallt 11
T1 called
T0 called
T1 called
T1 called

The second stores each bit of the binary representation for the value as a nul-terminated string and prints the result:

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

#define BITS_PER_LONG 64    /* define as needed */

char *bincpy (char *s, unsigned long v, unsigned sz);

int main (int argc, char **argv) {

    unsigned long v = argc > 1 ? strtoul (argv[1], NULL, 10) : 24;
    char array[BITS_PER_LONG + 1] = "";

    printf (" values in array: %s\n", bincpy (array, v, 16));

    return 0;
}

/** copy 'sz' bits of the binary representation of 'v' to 's'.
 *  returns pointer to 's', on success, empty string otherwise.
 *  's' must be adequately sized to hold 'sz + 1' bytes.
 */
char *bincpy (char *s, unsigned long v, unsigned sz)
{
    if (!s || !sz) {
        *s = 0;
        return s;
    }
    if (!v) {
        *s = '0';
        *(s + 1) = 0;
        return s;
    }
    unsigned i;

    for (i = 0; i < sz; i++)
        s[i] = (v >> (sz - 1 - i)) & 1 ? '1' : '0';
    s[sz] = 0;

    return s;
}

Example Use/Output

(padding to 16 bits)

$ ./bin/dec2binarray
 values in array: 0000000000011000

$ ./bin/dec2binarray 11
 values in array: 0000000000001011
David C. Rankin
  • 81,885
  • 6
  • 58
  • 85