0

Im confused on how to write the last 5 numbers in an array into binary. I know how to convert in general just keep diving by 2 and write out the remainder until the end but trying to transfer it into code is difficult. i_array is just an element of 100 numbers, NUM_TEST_ELEMENTS = 100. I tried attempting the code all the way at the bottom at step 7 but running it I can never get an output to print no matter where I put the print statement. Ignore the indent error it could not copy and paste correctly. I don't know how to properly write the code to do it and asking for any pointers on how to do it as I want to learn but don't know where to start.

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

  /* Local variables */
  float f_array[NUM_TEST_ELEMENTS];
  int i_array[NUM_TEST_ELEMENTS], i, j, temp;
  int hist_array[10];


  /* Step #1 - read in the float numbers to process */
  for (i = 0; i < NUM_TEST_ELEMENTS; i++) {
    scanf("%f", &f_array[i]);
  }
  for (i = 0; i < NUM_TEST_ELEMENTS; i++) {
    if (i % 2 == 0) {
      if (f_array[i] > 50) {
        f_array[i] *= 0.78;
      } else {
        f_array[i] *= 1.04;
      }
    }
    if (i % 2 != 0) {
      if (f_array[i] > 50) {
        f_array[i] *= 0.92;
      } else {
        f_array[i] *= 1.15;
      }
    }
  }

  void round311 (float f_array[], int i_array[]) {
    for (i = 0; i < NUM_TEST_ELEMENTS; i++) {
      i_array[i] = (int)(f_array[i] + 0.5);
    }
  }

  // Calling the function to Convert f_array into integers into i_array
  round311(f_array, i_array);

  void printfloatArr311(float f_array[]) {
    for (i = 0; i < NUM_TEST_ELEMENTS; i++) {
      printf("%.2f,", f_array[i]);
    }
  }
  printf("Testing printfloatArr311 (floats): ");
  printfloatArr311(f_array);
  printf("\n\n");


  //Prints out i_array 
  void printIntArr311(int i_array[]) {
    for (i=0; i<NUM_TEST_ELEMENTS; i++) {
      printf("%d, ", i_array[i]);
    }
  }
  printf("Testing printIntArr311 (integers): ");
  printIntArr311(i_array);
  printf("\n\n");


  void bubbleSort311(int i_array[]) {
    for (i = 0; i < NUM_TEST_ELEMENTS; i++) {
      for (j = 0; j < NUM_TEST_ELEMENTS - i - 1; j++) {
        if (i_array[j] > i_array[j+1]) {
          temp = i_array[j];
          i_array[j] = i_array[j+1];
          i_array[j+1] = temp;
        }
      }
    }
  }

  printf("Testing bubbleSort311 (integers): ");
  bubbleSort311(i_array);
  printIntArr311(i_array);
  printf("\n\n");

  /* Step #7 - print out the last 5 values of the integer array in binary. */
  printf("Testing toBinary:\n");
  for (i = NUM_TEST_ELEMENTS - 6; i < NUM_TEST_ELEMENTS; i++) {
    int toBinary(int i_array[]) {
      int extarr[8];
      j = 0;
      while(i_array[i] > 0) {
        extarr[i] = i_array[i] % 2;
        i_array[i] = i_array[i] / 2;
        j++;
      }
      printf(extarr);
    }
  }
  printf("\n\n");
}

Im trying to get an output to look like below with the space between every fourth bit.

Testing toBinary:
0100 1111
0101 0011
0101 0101
0101 0111
0101 1010
0101 1100
  • This CodeReview question might help you: https://codereview.stackexchange.com/q/219994/200418 It provides the code needed to print any unsigned type in binary format with `printf()` (needs GCC or a compatible compiler). – alx Feb 06 '20 at 03:08
  • @CacahueteFrito Probably his classwork is to write a function to print int as binary digits, though. – okovko Feb 06 '20 at 03:13
  • @okovko He can always cast `int` to `uint64_t` and print it. He didn't specify, so I provided him something that might help him write the code he needs. From his code it's difficult to write an answer, but maybe he can get it himself. – alx Feb 06 '20 at 03:17

2 Answers2

1

Welcome to StackOverflow.

Your question is of a poor quality, but that's alright. Let's get you up to speed. For a start, I have formatted your code to a basic extent. My edit is not visible to the public until it is approved. You are unlikely to receive assistance when your code isn't formatted.

There's quite a bit going on in your code example that you should remove. On StackOverflow, you need to write your question as a Minimum Reproducible Example, or MRE for short. The only part you have a question about is the last part.

It looks like you are confused about functions in C. You have a very long main that should be split up into functions. You tried to write a function toBinary within main, but you should write it outside main (before it). Then inside main you use your loop to just call that function.

Also, you should do your own research before asking a question. This question has been solved before, so your question is probably going to be closed as a duplicate. You can find the answer here. There are several ways to do the task (you will see one way in the question using shifts, which you will probably learn about later, and in the third answer, there is the usual way, but using a string. The logic is the same, and I gave you some code below).

Don't be afraid to ask questions, just look around for the answer first!

For your specific case, I will help you out a bit. You should do something like this:

#include <stdint.h> // you need this for CHAR_BIT, the bits in a byte
                    // CHAR_BIT is 8 on any reasonable machine

void print_int_binary(int x) {
    // bytes in an integer times bits in a byte
    // is the amount of bits in an integer
    // this changes depending on what machine you compile on
    // so don't use a hardcoded value
    // sizeof(int) is usually 4 or 8, sometimes 2 (old machines)
    int bits[sizeof(int) * CHAR_BIT];
    int i = 0;
    while(x > 0) {
      bits[i] = x % 2;
      x /= 2;
      i++;
    }
    // to print an array of integers in C
    // sizeof(array_name) works if the array has not decayed to a pointer
    for (int i = sizeof(bits) - 1; i >= 0; i--) {
      if (i != 0 && i % 4 == 0 && i != sizeof(bits) - 1) {
        // print a space between each 4 bits, not at the start or end
        printf(" ");
      }
      printf("%d", bits[i]);
    }
}

int main (int argc, char **argv) {
// the rest...

  /* Step #7 - print out the last 5 values of the integer array in binary. */
  printf("Testing toBinary:\n");
  for (i = NUM_TEST_ELEMENTS - 6; i < NUM_TEST_ELEMENTS; i++) {
      // i'll leave it up to you to figure out how to call the function
    }
  }
  printf("\n\n");
}

The code I gave you might not work precisely but it is a good starting point and the right idea. Note that the rightmost bit to print goes into bits[0], so to print a decimal number as binary, you'll need to print in reverse (so loop from max-1 to 0).

Look at the second answer here for details about array to pointer decay. In C++, you can use std::array to avoid decay.

okovko
  • 1,485
  • 8
  • 21
  • That link to an answer points to a C++ question & answer. This is a C one. However, there probably exists a duplicate in C. – alx Feb 06 '20 at 02:57
  • 1
    @CacahueteFrito Yes, sorry, admittedly I barely looked at the link. Google doesn't discern searches for "C" from searches for "C++". I still forget. I'll look for a better one and update the link. – okovko Feb 06 '20 at 03:17
  • @CacahueteFrito It's hard to find an example that does it the way his starting code tried to do it. He's making an array of integers instead of a string. Oh well, I gave him some code that should do it. – okovko Feb 06 '20 at 03:25
1

You have a number of misconceptions about C. (1) C does not allow function nested within main() and (2) printf (extarr); does not do what you think it does.

To begin with you will need to move all your functions outside of main(), e.g.

#include <stdio.h>

#define NUM_TEST_ELEMENTS 100

void round311 (float *f_array, int *i_array)
{
    for (int i = 0; i < NUM_TEST_ELEMENTS; i++)
        i_array[i] = (int)(f_array[i] + 0.5);
}

void printfloatArr311 (float *f_array)
{
    for (int i = 0; i < NUM_TEST_ELEMENTS; i++)
        printf ("%.2f,", f_array[i]);
}

void printIntArr311 (int *i_array)
{
    for (int i = 0; i < NUM_TEST_ELEMENTS; i++)
        printf ("%d, ", i_array[i]);
}
...
/* remaining functions */

(note: on access (subject to 4-exceptions, not relevant here), an array is converted to a pointer to the first element. So for the parameter, you can simply make it explicit that a pointer is being passed with int *i_array, C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3))

This leaves you with a large amount of reworking to your main(). First, you are not passing any arguments into main() so remove int argc, char **argv and replace it with void, see: C11 Standard - §5.1.2.2.1 Program startup(p1).

Next, remove the unused variables int hist_array[10];, etc.. and unless you are using a C89 compiler, you can move i, j into the loop declarations as was done in the functions above.

Your main() then can be something like:

int main (void) {

    /* Local variables */
    float f_array[NUM_TEST_ELEMENTS] = { 0. };
    int i_array[NUM_TEST_ELEMENTS] = { 0 };

    /* Step #1 - read in the float numbers to process */
    for (int i=0; i<NUM_TEST_ELEMENTS; i++) {
        if (scanf("%f", &f_array[i]) != 1) {    /* validate EVERY input */
            fprintf (stderr, "error: invalid float value (no. %d)\n", i);
            return 1;
        }
    }

    for (int i=0; i<NUM_TEST_ELEMENTS; i++){
        if (i % 2 == 0) {
            if (f_array[i]>50)
                f_array[i] *= 0.78;
            else
                f_array[i] *= 1.04;
        }
        else {  /* if it's not even -- then it is odd */
            if (f_array[i]>50)
                f_array[i] *= 0.92;
            else
                f_array[i] *= 1.15;
        }
    }

    // Calling the function to Convert f_array into integers into i_array
    round311(f_array, i_array);

    fputs ( "Testing printfloatArr311 (floats): ", stdout);
    printfloatArr311 (f_array);
    puts ("\n");

    //Prints out i_array 
    fputs ("Testing printIntArr311 (integers): ", stdout);
    printIntArr311 (i_array);
    puts ("\n");

    fputs ( "Testing bubbleSort311 (integers): ", stdout);
    bubbleSort311( i_array );
    printIntArr311( i_array );
    puts ("\n");

    /* Step #7 - print out the last 5 values of the integer array in binary. */
    printf( "Testing toBinary:\n" );
    for (int i = NUM_TEST_ELEMENTS - 5; i < NUM_TEST_ELEMENTS; i++)
        toBinary (i_array[i]);
    printf("\n\n");

}

That leaves toBinary(). When you are wanting to display the binary representation of a number, when you % 2 and then / 2 the bits are in reverse order. To properly display the number you need to buffer the digits (or better characters '0' and '1') and then output the binary representation as a string. You want every 4-bits separated by the '-' character, so you will need to count bits and insert the '-' where required. There are many ways to do this, but keeping with your attempt, you can do something like the following:

void toBinary (unsigned i)
{
    char extarr[128] = "";
    int j = sizeof extarr - 2,
        n = 0;

    while (i > 0) {
        if (n && n % 4 == 0)
            extarr[j--] = '-';
        extarr[j--] = (i % 2) + '0';
        i = i / 2;
        n++;
    }
    puts (&extarr[j+1]);
}

Your binary output for the last 5 sorted values 28741, 29558, 29627, 29898, 29969 would be, e.g.:

Testing toBinary:
111-0000-0100-0101
111-0011-0111-0110
111-0011-1011-1011
111-0100-1100-1010
111-0101-0001-0001

Or with a ' ' (space) separator:

Testing toBinary:
111 0000 0100 0101
111 0011 0111 0110
111 0011 1011 1011
111 0100 1100 1010
111 0101 0001 0001

Putting it altogether, you would have:

#include <stdio.h>

#define NUM_TEST_ELEMENTS 100

void round311 (float *f_array, int *i_array)
{
    for (int i = 0; i < NUM_TEST_ELEMENTS; i++)
        i_array[i] = (int)(f_array[i] + 0.5);
}

void printfloatArr311 (float *f_array)
{
    for (int i = 0; i < NUM_TEST_ELEMENTS; i++)
        printf ("%.2f,", f_array[i]);
}

void printIntArr311 (int *i_array)
{
    for (int i = 0; i < NUM_TEST_ELEMENTS; i++)
        printf ("%d, ", i_array[i]);
}

void bubbleSort311 (int *i_array)
{
    for (int i = 0; i < NUM_TEST_ELEMENTS; i++)
        for (int j = 0; j < NUM_TEST_ELEMENTS - i - 1; j++)
            if (i_array[j] > i_array[j+1]) {
                int temp = i_array[j];
                i_array[j] = i_array[j+1];
                i_array[j+1] = temp;
            }
}

void toBinary (unsigned i)
{
    char extarr[128] = "";
    int j = sizeof extarr - 2,
        n = 0;

    while (i > 0) {
        if (n && n % 4 == 0)
            extarr[j--] = '-';
        extarr[j--] = (i % 2) + '0';
        i = i / 2;
        n++;
    }
    puts (&extarr[j+1]);
}

int main (void) {

    /* Local variables */
    float f_array[NUM_TEST_ELEMENTS] = { 0. };
    int i_array[NUM_TEST_ELEMENTS] = { 0 };

    /* Step #1 - read in the float numbers to process */
    for (int i=0; i<NUM_TEST_ELEMENTS; i++) {
        if (scanf("%f", &f_array[i]) != 1) {    /* validate EVERY input */
            fprintf (stderr, "error: invalid float value (no. %d)\n", i);
            return 1;
        }
    }

    for (int i=0; i<NUM_TEST_ELEMENTS; i++){
        if (i % 2 == 0) {
            if (f_array[i]>50)
                f_array[i] *= 0.78;
            else
                f_array[i] *= 1.04;
        }
        else {  /* if it's not even -- then it is odd */
            if (f_array[i]>50)
                f_array[i] *= 0.92;
            else
                f_array[i] *= 1.15;
        }
    }

    // Calling the function to Convert f_array into integers into i_array
    round311(f_array, i_array);

    fputs ( "Testing printfloatArr311 (floats): ", stdout);
    printfloatArr311 (f_array);
    puts ("\n");

    //Prints out i_array 
    fputs ("Testing printIntArr311 (integers): ", stdout);
    printIntArr311 (i_array);
    puts ("\n");

    fputs ( "Testing bubbleSort311 (integers): ", stdout);
    bubbleSort311( i_array );
    printIntArr311( i_array );
    puts ("\n");

    /* Step #7 - print out the last 5 values of the integer array in binary. */
    printf( "Testing toBinary:\n" );
    for (int i = NUM_TEST_ELEMENTS - 5; i < NUM_TEST_ELEMENTS; i++)
        toBinary (i_array[i]);
    printf("\n\n");

}

Look things over and let me know if you have further questions.

David C. Rankin
  • 69,681
  • 6
  • 44
  • 72