Support LQ: Use code LQ3 and save \$3 on Domain Registration
 Home Forums HCL Reviews Tutorials Articles Register Search Today's Posts Mark Forums Read
 LinuxQuestions.org Programming C- shift bits will not work right!
 Programming This forum is for all programming questions. The question does not have to be directly related to Linux and any language is fair game.

Notices

05-21-2013, 06:08 AM   #16
H_TeXMeX_H
LQ Guru

Registered: Oct 2005
Location: \$RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep:

Quote:
 Originally Posted by PeterUK Thanks, I did over some more but if still to really sort what I wanted to do which was treat everything in binary. I did the following: Code: ```signed int d; d=7; printf ("This is d value in hex %x \n", d); printf ("This is d value in hex %X \n", d); printf ("This is d value in hex 0x%x \n", d); d = d << 2; printf ("This is d value in hex %x \n", d); printf ("This is d value in hex %d \n", d); exit (EXIT_SUCCESS); }``` output: This is d value in hex 7 This is d value in hex 7 This is d value in hex 0x7 This is d value in hex 1c This is d value in hex 28 Which it is expected and I understand it, but its not really what I wanted to do I wanted to be able to work on binary :-(
Trust me, with larger values, it is much harder to work in binary than in hex. As posted above, non-standard support for %b exists.

If you were to write out the full integer value (assuming 4 bytes), it would be 0x00000007 -> 0x0000001c. In binary that would be 00000000000000000000000000000111 -> 00000000000000000000000000011100.

Last edited by H_TeXMeX_H; 05-21-2013 at 06:22 AM.

05-23-2013, 11:23 AM   #17
PeterUK
Member

Registered: May 2009
Posts: 277

Original Poster
Rep:
Quote:
 Originally Posted by NevemTeve try some test like this: Code: ```int main (void) { int i; for (i=128; i<256; ++i) { printf ("%d %d 0x%x 0%o\n" , (signed char)i, (unsigned char)i, i, ); } }``` Also you can convert into other bases: Code: ```char *utostr (char *to, unsigned n, unsigned base /* 2..36 */) { char *p= to; do { int digit = n%base; *p++ = "0123456789abcdefghijklmnopqrstuvwxyz"[digit]; n /= base; } while (n); *p= '\0'; strrev (to); return to; } char *ntostr (char *to, int n, unsigned base /* 2..36 */) { if (n<0) { *to= '-'; utostr (to+1, -n, base); } else { utostr (to, n, base); } return to; }```
Are you sure is this C?

I tried and after changing some things I getting this error:
Code:
```test.c:28:5: warning: implicit declaration of function 'strrev' [-Wimplicit-function-declaration]
/tmp/ccksPa0X.o: In function `utostr.2488':
test.c:(.text+0x4f): undefined reference to `strrev'
collect2: error: ld returned 1 exit status
make: *** [test] Error 1```
Would you mind give me a simple example, like 7 to display 111. Thanks

05-23-2013, 11:59 AM   #18
johnsfine
LQ Guru

Registered: Dec 2007
Distribution: Centos
Posts: 5,272

Rep:
Quote:
 Originally Posted by PeterUK Are you sure is this C?
It was C, apparently not GNU C.

strrev is an extra item in string.h in some implementations of the C library. But apparently not in the GNU C library normally used in Linux.

You can easily find a definition of strrev with a google search and included that in your own source code.

Alternately, it should be easy for a beginning C programmer to rewrite utostr to not need strrev (the easiest way to code that is as a recursive function).

Last edited by johnsfine; 05-23-2013 at 12:03 PM.

05-23-2013, 12:03 PM   #19
dwhitney67
Senior Member

Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,533

Rep:
Quote:
 Originally Posted by PeterUK Would you mind give me a simple example, like 7 to display 111. Thanks
Give a person a fish, and you've fed them for the day. Teach them to catch fish, and you've fed them for a lifetime.

There is no automatic way to convert a base-10 number to binary (base-2). You will need to do this yourself. If I may suggest, you should attempt to use the modulo and division operations. For example:
Code:
```value = 7;
remainder = value % 2;   // This will yield a value of 1

value /= 2;
remainder = value % 2;   // This will yield a value of 1

value /= 2;
remainder = value % 2;   // This will yield a value of 1```
Since this is obviously an attempt on your behalf to learn something new (perhaps for coursework?), I will not offer any complete solution until you present what you have accomplished thus far.

05-23-2013, 03:11 PM   #20
PeterUK
Member

Registered: May 2009
Posts: 277

Original Poster
Rep:
Quote:
 Originally Posted by johnsfine It was C, apparently not GNU C. strrev is an extra item in string.h in some implementations of the C library. But apparently not in the GNU C library normally used in Linux. You can easily find a definition of strrev with a google search and included that in your own source code. Alternately, it should be easy for a beginning C programmer to rewrite utostr to not need strrev (the easiest way to code that is as a recursive function).
I always search before to write here, and I dint find much information about utostr and where it was it didnt look like C.

Also said I find one one but it mean from binary to Unsigned shift and back.

Also I am doing it as learning exercise no course work! already have two different program to do it, now I am trying to implement what NevemTeve suggested but I rather learning from something than work that spend lot of time debugging uses code. Because I today I waste time looking for this on header files and on internet I though It was a library missing link or declaration and I may just waste the time.

today I did this trying to test his script:

Code:
```#include <stdio.h>
#include <stdlib.h>

int main (void)
{

unsigned char result = 255;
char *to = malloc(254);
printf ("255 = %d\n", result);
result = result << 2; /* result <<= 2 */
printf ("255 << 2 = %d\n", result);

char *utostr (char *to, unsigned n, unsigned base) // 2..36

{
char *p= to;

do {
int digit = n%base;
*p++ = "0123456789abcdefghijklmnopqrstuvwxyz"[digit];
n /= base;
} while (n);
*p= '\0';
strrev (to);

}

utostr (to, 8, 2);

printf ("254 binary = %s\n", to);

exit (EXIT_SUCCESS);
}```
I think the great about forums is you could get help and keep moving faster that by your own, if not what is the point?

Last edited by PeterUK; 05-23-2013 at 03:12 PM.

05-23-2013, 03:21 PM   #21
johnsfine
LQ Guru

Registered: Dec 2007
Distribution: Centos
Posts: 5,272

Rep:
Quote:
 Originally Posted by PeterUK I always search before to write here, and I dint find much information about utostr and where it was it didnt look like C.
I assume utostr was just a name NevemTeve made up. I didn't bother to google it.

My google suggestion was for strrev.

But why does utostr not look like C? It is C code that includes a call to one function that the headers don't declare.

05-23-2013, 03:58 PM   #22
PeterUK
Member

Registered: May 2009
Posts: 277

Original Poster
Rep:
Quote:
 Originally Posted by johnsfine I assume utostr was just a name NevemTeve made up. I didn't bother to google it. My google suggestion was for strrev. But why does utostr not look like C? It is C code that includes a call to one function that the headers don't declare.
I did a search on goggle for utostr and where I have found it it was not like C. I also reach for "strrev" but as the error for the compiler "implicit declaration of function 'strrev'"

05-23-2013, 04:02 PM   #23
PeterUK
Member

Registered: May 2009
Posts: 277

Original Poster
Rep:
Quote:
 Originally Posted by johnsfine It was C, apparently not GNU C. strrev is an extra item in string.h in some implementations of the C library. But apparently not in the GNU C library normally used in Linux. You can easily find a definition of strrev with a google search and included that in your own source code. Alternately, it should be easy for a beginning C programmer to rewrite utostr to not need strrev (the easiest way to code that is as a recursive function).
I did add earlier today "#include <string.h>" but it didnt work. as you see if you google strrev the first page is flooded by PHP and Java code.

05-23-2013, 04:44 PM   #24
dwhitney67
Senior Member

Registered: Jun 2006
Location: Maryland
Distribution: Kubuntu, Fedora, RHEL
Posts: 1,533

Rep:
Quote:
 Originally Posted by PeterUK I did add earlier today "#include " but it didnt work. as you see if you google strrev the first page is flooded by PHP and Java code.
Trying Googling for "C reverse string".

 05-23-2013, 04:55 PM #25 johnsfine LQ Guru   Registered: Dec 2007 Distribution: Centos Posts: 5,272 Rep: I actually googled for C strrev and for GNU strrev I ignored some PHP and other irrelevant hits and found mostly pages mentioning one way or another than GNU C libraries don't include strrev. Some of those tell you how to define your own strrev, though that is so trivial, you should not need to be told. How to narrow a google search that includes too much off topic is also trivial enough that most of us don't need to be told. You ought to put some effort into learning how to use your tools.
05-23-2013, 05:29 PM   #26
PeterUK
Member

Registered: May 2009
Posts: 277

Original Poster
Rep:
Quote:
 Originally Posted by johnsfine I actually googled for C strrev and for GNU strrev I ignored some PHP and other irrelevant hits and found mostly pages mentioning one way or another than GNU C libraries don't include strrev. Some of those tell you how to define your own strrev, though that is so trivial, you should not need to be told. How to narrow a google search that includes too much off topic is also trivial enough that most of us don't need to be told. You ought to put some effort into learning how to use your tools.
Its here chill out!

some code for how is really following:

Code:
```#include <string.h>
#include <stdio.h>
#include <stdlib.h>
char *strrev(char *str)
{
char *p1, *p2;

if (! str || ! *str)
return str;
for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
{
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return str;
}

int main()
{

unsigned char result = 255;
char *to = malloc(254);
printf ("255 = %d\n", result);
result = result << 2; /* result <<= 2 */
printf ("255 << 2 = %d\n", result);

char *utostr (char *to, unsigned n, unsigned base) // 2..36

{
char *p= to;

do {
int digit = n%base;
*p++ = "0123456789abcdefghijklmnopqrstuvwxyz"[digit];
n /= base;
} while (n);
*p= '\0';
strrev (to);

}

utostr (to, 254, 2);

printf ("254 binary = %s\n", to);

exit (EXIT_SUCCESS);

}```
Third was to do it. (I still need to digest his utostr code)

Last edited by PeterUK; 05-23-2013 at 05:30 PM.

 05-24-2013, 02:17 AM #27 NevemTeve Senior Member   Registered: Oct 2011 Location: Budapest Distribution: Debian/GNU/Linux, AIX Posts: 2,521 Rep: strrev is a masterpiece of human mind, I could sell it for billion euros... oh never mind: Code: ```char *strrev (char *str) { char *p= str; char *q; if (!p || !*p) return p; p= str; for (q= p+strlen(p)-1; p
05-24-2013, 03:42 AM   #28
PeterUK
Member

Registered: May 2009
Posts: 277

Original Poster
Rep:
Quote:
 Originally Posted by NevemTeve strrev is a masterpiece of human mind, I could sell it for billion euros... oh never mind: Code: ```char *strrev (char *str) { char *p= str; char *q; if (!p || !*p) return p; p= str; for (q= p+strlen(p)-1; p
;-) so you name is Bob? :-)

The Thread has turn out into something else, I posted because one the program was not giving the right output, and the reason I start looking a bit manipulation in C through my review it was because I wanted to emulate some HDL code in C, I find it strange that the machine is a bit buss has not got some option work on bit register as its. But I learn working on this Thread something I didn't know and it was that the compiler can print in assembler, so maybe that is the answer, now I need to know if you could work the other way around do the code in assembler and add use GCC to compile it?

 05-24-2013, 04:45 AM #29 NevemTeve Senior Member   Registered: Oct 2011 Location: Budapest Distribution: Debian/GNU/Linux, AIX Posts: 2,521 Rep: 1. No, it is NevemTeve. 2. Yes, you can insert Assembly parts into C-source (it is a non-standard gcc-extension), but you really shouldn't -- that's not for beginners.