One for the program...
 

  You don't need to be an 'investor' to invest in Singletrack: 6 days left: 95% of target - Find out more

[Closed] One for the programmers! (Hex content)

42 Posts
10 Users
0 Reactions
73 Views
Posts: 4954
Free Member
Topic starter
 

I just need a quick pointer if I may.

I have a function that returns a integer g() I need to do this

int b = g() & 0xff

what the best way to do this?

int b = g() & 255;

or can I should I use

int b = g() & xtoi(ff);

Last one. Any idea how I only output the first byte of b to std out?

May be just set all bits > 7 to 0?


 
Posted : 30/06/2011 8:46 am
Posts: 91000
Free Member
 

Doesn't it depend on the language? Looks like C++?

Surely there's a way to type in hex literals in your language? Your first statement should work I think.

As for the first seven bits.. just output the remainder of dividing by 128, or you could use a cast or conversion function to make it as clear as possible to anyone reading the code.


 
Posted : 30/06/2011 8:48 am
Posts: 11402
Free Member
 

((char*)&b)[0]
((char*)&b)[1]
((char*)&b)[2]
((char*)&b)[3]

works in c/c++


 
Posted : 30/06/2011 8:56 am
Posts: 0
Free Member
 

I just need a quick pointer if I may.

Here you go: *
😀


 
Posted : 30/06/2011 9:19 am
Posts: 621
Free Member
 

glenh - Member

I just need a quick pointer if I may.

Here you go: *

😆


 
Posted : 30/06/2011 9:23 am
Posts: 31206
Full Member
 

I have a function that returns a integer g() I need to do this

int b = g() & 0xff

So why can't you just do that? Should work well enough. If it makes you happier you could break it into two statements:

[code]int b = g();
b &= 0xff;[/code]


 
Posted : 30/06/2011 9:30 am
Posts: 106
Free Member
 

[code]GrahamS++;[/code]


 
Posted : 30/06/2011 9:39 am
Posts: 3284
Full Member
 

what grahams says

to output the first byte of b you output the result of b & 0xff - you seem to have done that already


 
Posted : 30/06/2011 9:45 am
Posts: 4954
Free Member
Topic starter
 

molgrips - Member
Doesn't it depend on the language? Looks like C++?

yep sorry C++

molgrips - Member
Surely there's a way to type in hex literals in your language? Your first statement should work I think.

My googling terms must be off as I (clearly) don't know what I'm on about!

The first method dose not work, it was initial thoughts.

molgrips - Member

As for the first seven bits.. [b]just output the remainder of dividing by 128,[/b] or you could use a cast or conversion function to make it as clear as possible to anyone reading the code.

Are you saying to a left shift of 8 bit (to get rid of anything in front of bits 0- 7) then redivide by 128 to shift it back with resulting in the bits > 7 being zero? This would only work if you can guarantee that int is 2 bytes long? Or I could do

int8_t c = b

but this would only take the 8 most significant bits.

Klunk - Member
((char*)&b)[0]
((char*)&b)[1]
((char*)&b)[2]
((char*)&b)[3]

works in c/c++

Thanks I'll have a play with this, I'm not sure I get it though.

((char*)&b)[0] = cast to a char pointer the zero element of a bit wise & of b and what?

Sorry very much on the learning curve of C++ and these low level operations!

glenh - Member
I just need a quick pointer if I may.

Here you go: *

Booom tish!!! 🙂


 
Posted : 30/06/2011 9:49 am
Posts: 4954
Free Member
Topic starter
 

So why can't you just do that? Should work well enough. If it makes you happier you could break it into two statements:

int b = g();
b &= 0xff;

I had tried it and it was not working, not even compiling...

but... I just realised I had copied the Hex from a txt document and it was in txt doc as

Oxff instead of 0xff

and because all this hex stuff is new I thought there was something deeper wrong going on.

Doh!

Trying to work too fast and panicking!!

Still not sure about the best way of only dealing with the first byte.


 
Posted : 30/06/2011 9:52 am
Posts: 11402
Free Member
 

((char*)&b)[0] = cast to a char pointer the zero element of a bit wise & of b and what?

casts the address of b (&b) to a pointer to 4 chars (char*), return the first char [0] (1st byte) of the integer.


 
Posted : 30/06/2011 9:57 am
Posts: 31206
Full Member
 

Oxff instead of 0xff

Ahh schoolboy error.

Step One: make sure your chosen editor uses a font where you can clearly distinguish:

0 vs O
l vs 1 vs |
. vs ,
: vs ;

I tend to use [url= http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=17879 ]Consolas[/url] which was specially designed by Microsoft for use in programming.


 
Posted : 30/06/2011 9:58 am
Posts: 4954
Free Member
Topic starter
 

@Klunk ahhh make sense, I was reading it all wrong!! Thanks


 
Posted : 30/06/2011 10:00 am
Posts: 91000
Free Member
 

Are you saying to a left shift of 8 bit.. [snip]

No I'm saying divide whatever number it is by 128 then take the remainder.

So that's b % 128 in this case I believe, although IANAC++P of course.

Take 297 - it's 100101001 in binary. First 7 bits are 0101001 which is 41. 297 divided by 128 is 2 remainder 41. Which is what that % operator does.


 
Posted : 30/06/2011 10:00 am
Posts: 4954
Free Member
Topic starter
 

Ahh schoolboy error.

indeed. My editor dose but I was not looking out for it, as soon at I changer O->0 nice orange txt for hex value!


 
Posted : 30/06/2011 10:02 am
Posts: 106
Free Member
 

Oxff instead of 0xff

Oh the joy of using non-programming-specific fonts 😀

((char*)&b)[0] = cast to a char pointer the zero element of a bit wise & of b and what?

Klunk's little hack is a way to address the individual bytes of b in memory as a char array. The unary "&" in "&b" is not a bitwise operator but gives the address of b in memory. All legal but the order the bytes come out will depend on the endian-ness of your system!

Simpler, clearer and more portable to just use:-

b & 0xFF
( b >> 8 ) & 0xFF
( b >> 16 ) & 0xFF
( b >> 24 ) & 0xFF

[EDIT] ninja-ed... doh

Oh, and Miriam Fixed with some custom tweaks...


 
Posted : 30/06/2011 10:02 am
Posts: 4954
Free Member
Topic starter
 

b % 128

<penny drops>


 
Posted : 30/06/2011 10:09 am
Posts: 4954
Free Member
Topic starter
 

I think it might be b % 127 actually...


 
Posted : 30/06/2011 10:12 am
Posts: 91000
Free Member
 

I tried it, it's 128.


 
Posted : 30/06/2011 10:19 am
Posts: 4954
Free Member
Topic starter
 

Actually I know that g returns a 32 bit integer and that it's most significant bit is 0 so +ve.

I need the first byte from

int b = g() & 0xff

so I think it will be

b % 256

that I want.

EDIT: thinking allowed I was wrong

forget it the & on

int b = g() & 0xff

greater that all bits > 7 will be 0.


 
Posted : 30/06/2011 10:29 am
Posts: 106
Free Member
 

What you want is (1) the actual contents of the byte you're interested in.

...you already have this: it's [code]b = g() & 0xFF[/code].

And (2) output in the format you want.

...in plain C you could do this with:-

[code]printf("0x%02X", b);[/code]

Dunno why you're all heading off down that "% 128" rabbithole...


 
Posted : 30/06/2011 10:37 am
Posts: 3284
Full Member
 

what elliptic (and me) said


 
Posted : 30/06/2011 10:55 am
Posts: 91000
Free Member
 

Dunno why you're all heading off down that "% 128" rabbithole...

Why's it a rabbit hole? It's simple, succinct and neat, and it works.


 
Posted : 30/06/2011 11:04 am
Posts: 4954
Free Member
Topic starter
 

My spec is below. I was taking it that I need to have it out as a dec number but truncated to one bit range. i.e. 0 if 256

// output exactly one byte = (g() & 0xff) to stdout
// Note: Output will always be ASCII text when
// functioning correctly and will use '\n' (= 0x0A) to indicate new-line.


 
Posted : 30/06/2011 12:14 pm
Posts: 91000
Free Member
 

You have your numeric value, just use printf or >> or whatever you are using.


 
Posted : 30/06/2011 12:28 pm
Posts: 3284
Full Member
 

TheBrick do you do this for a living? or are you a student or something?


 
Posted : 30/06/2011 12:35 pm
Posts: 106
Free Member
 

// output exactly one byte = (g() & 0xff) to stdout
// Note: Output will always be ASCII text when
// functioning correctly and will use '\n' (= 0x0A) to indicate new-line.

So taking this spec literally, what you actually want is:-

[code]char b = g() & 0xFF;
printf("%c", b);
[/code]

which will send exactly one byte to stdout, to be displayed as an ASCII character.

Note that [code]b[/code] is declared as [code]char[/code] not [code]int[/code] which is important because [code]printf()[/code] is variadic, therefore does not do argument type conversion.


 
Posted : 30/06/2011 12:51 pm
Posts: 0
Free Member
 

Of course if you're happy being dirty, then:

[code]printf("%c", (char) g());[/code]


 
Posted : 30/06/2011 12:58 pm
Posts: 0
Free Member
 

% 128 is both disgusting and wrong.

If you really wanted to do a divide to get one byte (bits 0-7) out, you could use % 256.

It would be a sick and twisted thing to do though, using a divide operator (slow) to do a bitwise and operator. Yuck. People sticking things like that into frequently called code are so often a cause of stuff running inexplicably slow.

Very unclear, as it kind of implies that you are doing maths, rather than just getting bits out. Plus it relies on the underlying number representation, which whilst it is usually the same, isn't guaranteed to be. It also is slightly unclear with negative numbers, as the modulo operator does different things in different languages sometimes, so if you get some poor person coming from one of those languages this will be unclear to them.


 
Posted : 30/06/2011 1:24 pm
Posts: 106
Free Member
 

joemarshall++

Of course if you're happy being dirty, then:

printf("%c", (char) g());

Or just:-

[code]putchar(g());[/code]


 
Posted : 30/06/2011 1:27 pm
Posts: 91000
Free Member
 

% 128 is both disgusting and wrong.

If you really wanted to do a divide to get one byte (bits 0-7) out, you could use % 256.

He originally said the first seven bits, so it wasn't wrong then.

People sticking things like that into frequently called code are so often a cause of stuff running inexplicably slow

That depends on what you're coding, doesn't it? In my world the number of clock cycles that takes is utterly trivial.

It also is slightly unclear with negative numbers, as the modulo operator does different things in different languages sometimes

That is a fair point


 
Posted : 30/06/2011 1:44 pm
Posts: 106
Free Member
 

In my world the number of clock cycles that takes is utterly trivial.

In my world it's the difference between one clock cycle and several hundred, which is very non-trivial.

And more broadly...

Very unclear, as it kind of implies that you are doing maths, rather than just getting bits out.

...is bang on the money. Source code is written for other programmers to read, not just the machine.


 
Posted : 30/06/2011 1:52 pm
Posts: 91000
Free Member
 

Source code is written for other programmers to read, not just the machine

That's exactly why I chose that syntax. Just goes to show how that's matter of taste isn't it? 🙂 In reality of course, a comment would be required here either way. And I usually advocate not putting in comments.

In my world it's the difference between one clock cycle and several hundred, which is very non-trivial.

Several hundred clock cycles for modulo operator? On an interger? Seems a lot...


 
Posted : 30/06/2011 2:09 pm
Posts: 106
Free Member
 

Several hundred clock cycles for modulo operator? On an interger? Seems a lot...

Well, I guess a reasonable compiler might be smart enough to spot mod-power-of-two and optimise that into a bitwise-AND. Mine does in fact, I just checked, but I certainly wouldn't depend on it.

I also checked a more general case (% 123) on the platform I usually develop for (16-bit DSP) and it generates a call into the division library which takes 490 cycles to execute. On a device that's typically clocked at ~25MHz, yes MHz.


 
Posted : 30/06/2011 2:47 pm
Posts: 91000
Free Member
 

Still don't get why integer division would take that many cycles, but I dunno much about cpu architecture and operation 🙂


 
Posted : 30/06/2011 2:55 pm
Posts: 4954
Free Member
Topic starter
 

molgrips - Member
You have your numeric value, just use printf or >> or whatever you are using.

That is what I have done now.

So taking this spec literally, what you actually want is:-

char b = g() & 0xFF;
printf("%c", b);

My original plan was going to use char because it's one bite but then it was not clear tome if for example the result was 65 if they wanted 65' output or, or the 65th ANSI characterA'.

Re-reading it I think you are correct in the interpretation.

llama - Member
TheBrick do you do this for a living? or are you a student or something?

Neither I'm unemployed. I've been "programming" for years but I have need MATLAB and a little Java in my first Job and then over the past few years FORTRAN + BASH scripting + a little python. Never done much C / C++ only playing and [b]nothing[/b] at all to do with low level stuff like this. This is part of a job test thing so I am having to learn a lot of C/ C++ and stuff to with HEX / bitwise operation in a very short amount of time. This is why my questions and understanding is a bit slow! This is completely outside my expertise, as is obvious.

Thanks for all the help.


 
Posted : 30/06/2011 3:16 pm
Posts: 106
Free Member
 

I am having to learn a lot of C/ C++

Worth pointing out that C and C++ should be thought of as quite distinct languages 🙂

Although C++ is usually described as an extension of C there are some subtle differences that make it well worth being clear which one you are currently using (ie which mode your compiler is being invoked in...!)

stuff to with HEX / bitwise operation

It takes some getting your head around but mostly based on some fairly simple patterns: bitwise-OR | with a mask to set specific bits, bitwise-AND & with a "negative" mask to clear them, XOR ^ to flip them, left << and right >> shifts. Gets easier as you get more familiar with hex notation for bitmasks especially those for individual bits:- 0x1, 0x2, 0x4, 0x8, 0x10, 0x20 etc.


 
Posted : 30/06/2011 4:12 pm
Posts: 4954
Free Member
Topic starter
 

Although C++ is usually described as an extension of C there are some subtle differences that make it well worth being clear which one you are currently using (ie which mode your compiler is being invoked in...!)

Noted (g++ btw). I though C was a complete subset of C++ so any C code would be valid?

In this program I have not really used any C++ features, no OO. All I've used is cerr I think as it's a nice quick error message I can throw in.

It takes some getting your head around but mostly based on some fairly simple patterns: bitwise-OR | with a mask to set specific bits, bitwise-AND & with a "negative" mask to clear them, XOR ^ to flip them, left << and right >> shifts. Gets easier as you get more familiar with hex notation for bitmasks especially those for individual bits:- 0x1, 0x2, 0x4, 0x8, 0x10, 0x20 etc.

I think I've started to get my head around the operations is was as much was was meant by this one part of the specifications. "Talking" about the problem makes it clearer though.


 
Posted : 30/06/2011 8:11 pm
Posts: 0
Free Member
 

Well, I guess a reasonable compiler might be smart enough to spot mod-power-of-two and optimise that into a bitwise-AND. Mine does in fact, I just checked, but I certainly wouldn't depend on it

Most decent compilers will - I was going to point that out earlier - though as you say, you can't rely on it.

Still don't get why integer division would take that many cycles, but I dunno much about cpu architecture and operation

I'm surprised. Though I guess you work at a rather higher level than me. You do know how to do long division? Well integer division works just like that on a computer, though in binary. Hence for 32 bit integers you potentially have 32 times round a loop, each loop potentially consisting of 4 compares, 4 subtractions, 8 shifts - there's 512 cycles for you without any other loop overheads (elliptic has a 16 bit system, so you [b]should[/b] be able to divide that by 2). How else would a computer be able to do integer division?

I'm not really sure I understand "That's exactly why I chose that syntax. Just goes to show how that's matter of taste isn't it?" either, when as pointed out, [code]& 0xff[/code] (or [code]& 0x7f[/code]) makes it far clearer you're doing a mask than [code]% 256[/code] (or [code]% 128[/code]).


 
Posted : 30/06/2011 10:23 pm
Posts: 91000
Free Member
 

Though I guess you work at a rather higher level than me.

Yeah 🙂 I learned about how this stuff worked when I was a kid but I guess I forgot it. I was thinking that on modern platforms there'd be some kind of whizzy PLA or something that would do it in an instant rather than the CPU having to do it. I dunno how those things work tho. Maybe there is on a PC but not on these little embedded devices I dunno.

Re the syntax clarity - I agree that the mask is just as easy to read and possibly more appropriate, but I thought it was simpler than the bitwise operators. But then again perhaps that's cos that's not something I see a lot, whereas if you're writing and using this kind of code you're more used to it.


 
Posted : 01/07/2011 8:55 am
Posts: 31206
Full Member
 

Well integer division works just like that on a computer, though in binary. Hence for 32 bit integers you potentially have 32 times round a loop, each loop potentially consisting of 4 compares, 4 subtractions, 8 shifts - there's 512 cycles for you without any other loop overheads (elliptic has a 16 bit system, so you should be able to divide that by 2). How else would a computer be able to do integer division?

Well there are certainly [url= http://oopweb.com/Assembly/Documents/ArtOfAssembly/Volume/Chapter_6/CH06-2.html#HEADING2-451 ]DIV and IDIV instructions in x86 assembler[/url] so I don't think it takes as many CPU cycles as you think it does.


 
Posted : 01/07/2011 9:13 am
Posts: 91000
Free Member
 

Yes but each instruction has a clock cycle cost, Graham. Like I say it depends on how it's been implemented in the instruction set I guess. I seem to remember reading that x86 had instructions that did complex tasks and took many many cycles. Perhaps this is one of them.


 
Posted : 01/07/2011 9:26 am
Posts: 31206
Full Member
 

Yeah they do, but just not as many as aracer was suggesting.

Take a looky at this lovely document:
[url= http://download.intel.com/design/processor/manuals/248966.pdf ]Intel® 64 and IA-32 Architectures Optimization Reference Manual (PDF)[/url]

You'll be wanting Table C-13 which tells you the Latency for a DIV operation on a 0F_3H CPUID is between 66 and 80 cycles. 🙂


 
Posted : 01/07/2011 9:32 am

6 DAYS LEFT
We are currently at 95% of our target!