- This topic has 42 replies, 10 voices, and was last updated 12 years ago by GrahamS.
-
One for the programmers! (Hex content)
-
TheBrickFree Member
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?
molgripsFree MemberDoesn’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.
KlunkFree Member((char*)&b)[0]
((char*)&b)[1]
((char*)&b)[2]
((char*)&b)[3]works in c/c++
retro83Free Memberglenh – Member
I just need a quick pointer if I may.
Here you go: *
😆
GrahamSFull MemberI 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:
int b = g();
b &= 0xff;llamaFull Memberwhat grahams says
to output the first byte of b you output the result of b & 0xff – you seem to have done that already
TheBrickFree Membermolgrips – 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.. 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.
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!!! 🙂
TheBrickFree MemberSo 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.
KlunkFree 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.
GrahamSFull MemberOxff 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 Consolas which was specially designed by Microsoft for use in programming.
molgripsFree MemberAre 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.
TheBrickFree MemberAhh 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!
ellipticFree MemberOxff 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…
TheBrickFree MemberActually 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.
ellipticFree MemberWhat you want is (1) the actual contents of the byte you’re interested in.
…you already have this: it’s
b = g() & 0xFF
.And (2) output in the format you want.
…in plain C you could do this with:-
printf("0x%02X", b);
Dunno why you’re all heading off down that “% 128” rabbithole…
molgripsFree MemberDunno 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.
TheBrickFree MemberMy 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.molgripsFree MemberYou have your numeric value, just use printf or >> or whatever you are using.
llamaFull MemberTheBrick do you do this for a living? or are you a student or something?
ellipticFree 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:-
char b = g() & 0xFF;
printf("%c", b);
which will send exactly one byte to stdout, to be displayed as an ASCII character.
Note that
b
is declared aschar
notint
which is important becauseprintf()
is variadic, therefore does not do argument type conversion.aracerFree MemberOf course if you’re happy being dirty, then:
printf("%c", (char) g());
joemarshallFree 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.
ellipticFree Memberjoemarshall++
Of course if you’re happy being dirty, then:
printf(“%c”, (char) g());
Or just:-
putchar(g());
molgripsFree 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
ellipticFree MemberIn 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.
molgripsFree MemberSource 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…
ellipticFree MemberSeveral 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.
molgripsFree MemberStill don’t get why integer division would take that many cycles, but I dunno much about cpu architecture and operation 🙂
TheBrickFree Membermolgrips – 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 character
A’.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 nothing 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.
ellipticFree MemberI 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.
TheBrickFree MemberAlthough 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.
aracerFree MemberWell, 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 should 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,
& 0xff
(or& 0x7f
) makes it far clearer you’re doing a mask than% 256
(or% 128
).molgripsFree MemberThough 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.
The topic ‘One for the programmers! (Hex content)’ is closed to new replies.