PDA

View Full Version : trying to see if i can shorten this code any writen in C



bathacid
February 27th, 2012, 07:38 PM
sorry i am fairly new to programming and created a function that will take a random number generated by main and place it as the variable that i named "rc". then it takes it and turns the number in to binary. Would an array help shorten this?


int binary (int rc) {

//binary values
int x1 = 128;
int x2 = 64;
int x3 = 32;
int x4 = 16;
int x5 = 8;
int x6 = 4;
int x7 = 2;
int x8 = 1;

//value storage
int v1;
int v2;
int v3;
int v4;
int v5;
int v6;
int v7;

//one or zero value
int b1;
int b2;
int b3;
int b4;
int b5;
int b6;
int b7;
int b8;

if (rc >= x1) {
v1 = rc - x1;
b1 = 1;
}
else {
v1 = rc;
b1 = 0;
}
if (v1 >= x2) {
v2 = v1 -x2;
b2 = 1;
}
else {
v2 = v1;
b2 = 0;
}
if (v2 >= x3) {
v3 = v2 - x3;
b3 = 1;
}
else {
v3 = v2;
b3 = 0;
}
if (v3 >= x4) {
v4 = v3 - x4;
b4 = 1;
}
else {
v4 = v3;
b4 = 0;
}
if (v4 >= x5) {
v5 = v4 - x5;
b5 = 1;
}
else {
v5 = v4;
b5 = 0;
}
if (v5 >= x6) {
v6 = v5 - x6;
b6 = 1;
}
else {
v6 = v5;
b6 = 0;
}
if (v6 >= x7) {
v7 = v6 - x7;
b7 = 1;
}
else {
v7 = v6;
b7 = 0;
}
if (v7 >= x8) {
b8 = 1;
}
else {
b8 = 0;
}
printf( "The binary equlivent of that number is %d%d%d%d%d%d%d%d", b1, b2, b3, b4, b5, b6, b7, b8 );
return 0;
}

r-senior
February 27th, 2012, 08:09 PM
You can use a loop, you don't need an array.

Consider this:



01001110 & 10000000 == 0
01001110 & 01000000 == not zero
01001110 & 00100000 == 0
01001110 & 00010000 == 0
01001110 & 00001000 == not zero
01001110 & 00000100 == not zero
01001110 & 00000010 == not zero
01001110 & 00000001 == 0
...


The '&' is bitwise AND, not to be confused with '&&'. Zero is false, not zero is true.

Also look into the right shift operator.

satsujinka
February 27th, 2012, 08:17 PM
I second a loop. Though I'd ignore the bit-wise operators.

Here's a function that will print out a binary given a decimal. you call it with

dtob(your_decimal, 1)
and here it is:

void dtob(int decimal, int root) {
if decimal > 0 {
remainder = decimal % 2;
dtob(decimal/2, 0);
printf("%d", remainder);
} else if root{
printf("%d", decimal)
}
}

r-senior
February 27th, 2012, 09:29 PM
Nice recursive solution. Personally I think the second parameter makes calling it slightly untidy, but that's just being picky.

EDIT: Did you test it? It doesn't compile and it doesn't work for negative numbers.

@OP: this isn't homework is it?

satsujinka
February 27th, 2012, 11:13 PM
Nice recursive solution. Personally I think the second parameter makes calling it slightly untidy, but that's just being picky.

EDIT: Did you test it? It doesn't compile and it doesn't work for negative numbers.

@OP: this isn't homework is it?

No I didn't test it. I wrote it from a tablet. As for negative numbers... a test and negate would be enough to get those working, unless you want 2's complement and... well it's just easier to ignore negative numbers. The second int is unfortunately necessary if you want a single function. I'll update my post shortly with working code that's slightly more elegant.

UPDATE:
Here's working code, prints the absolute value of a number in binary.

#include <stdio.h>


void dtob(int decimal_number, int root) {
if(decimal_number > 0) {
int rem = decimal_number%2;
dtob(decimal_number/2, 0);
printf("%d", rem);
} else if(decimal_number ==0 && root)
printf("%d", decimal_number);
else if(decimal_number < 0)
dtob(-decimal_number, root);
}

//wrapper
void itob(int decimal_number) {
dtob(decimal_number, 1);
puts("\n");
}

int main () {
itob(46);
itob(-36);
itob(4);
return 0;
}

r-senior
February 27th, 2012, 11:23 PM
No I didn't test it. I wrote it from a tablet. As for negative numbers... a test and negate would be enough to get those working, unless you want 2's complement and... well it's just easier to ignore negative numbers. The second int is unfortunately necessary if you want a single function. I'll update my post shortly with working code that's slightly more elegant.
I tested it and it works once it compiles.

Based on previous posts from the OP, it doesn't look like homework, so here's my offering using bit masks and including spacing between groups of digits:


#ifndef GROUP_SIZE
#define GROUP_SIZE 8
#endif

/**
* Prints a binary representation of a number to stdout using
* a mask shifted from left to right.
*
* The binary digits are grouped in blocks of GROUP_SIZE digits.
* Define GROUP_SIZE == 0 for no grouping.
*
* @param n the number to print
*/
void print_binary(int n)
{
unsigned mask, bits = sizeof(int) * 8;

for (mask = 0x01 << bits - 1; bits--; mask >>= 1) {
putchar(mask & n ? '1' : '0');
if (GROUP_SIZE && bits % GROUP_SIZE == 0)
putchar(' ');
}
putchar('\n');
}

satsujinka
February 27th, 2012, 11:46 PM
@r-senior
gcc -Wall complains about your style choices, but otherwise that's nice and neat, gives 2's complement and everything.

Though the reason why I recommended against a bitwise solution, is simply that bathacid is a beginner and there's really not that many locations bitwise operators are useful (this being one of the few places it is) and techniques like recursion/iteration are much more useful to learn.

r-senior
February 28th, 2012, 12:12 AM
@r-senior
gcc -Wall complains about your style choices
How dare it! [-(

It doesn't like "0x01 << bits - 1" because I'm relying on operator precedence rather than parentheses. What's the point of operator precedence tables if you can't use them to put doubt in the minds of nervous programmers (and compilers)?

pbrane
February 28th, 2012, 01:34 AM
Another way to print a binary representation of a decimal number.


void binsprintf(char *s, int val)
{
char *p;
unsigned int t;
p = s;
t = 0x80000000; // scan 32 bits
for ( ; t > 0; t = t >> 1) {
if (val & t)
*p++ = '1';
else
*p++ = '0';
}
*p = 0;
}


pass in an allocated char array for the output string and the decimal value. You can change the value of 't' to suit the size of the bit string you need.