Click here to Skip to main content
15,884,176 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi,


I have a hex number for exp 0x156A , now I want to split least significant digit(4bit) seperately and the same way want to split each digits seperately.

Do anybody have any idea, how to do in C++ ???



Thanks,
Baakki
Posted
Comments
CPallini 7-Nov-13 5:23am    
It looks a pretty simple task, to me. What is your doubt about?

Assuming your hex number is in an integer or similar:
C++
int GetDigit(int value, int digitNumber)
   {
   return (value >> (4 * digitNumber)) & 0x000F;
   }
 
Share this answer
 
Comments
Baakki 7-Nov-13 6:33am    
Thank u for ur valuable suggestion dude....
CPallini 7-Nov-13 15:13pm    
5.
Mask the bits out you want, right shift down so that the result is in the lower bits.

So to get the 0x6 from 0x156A you'd first mask it out, and it is covered by 0xF0.
Then, because it is the second group of 4 bits shift that down by 4 bits.

Something like this might help you;

C++
#include <iostream>

using namespace std;

int main() {
	const int source = 0x156A;

	const int first_4 = (source & 0xF) >> 0;
	const int second_4 = (source & 0xF0) >> 4;
	const int third_4 = (source & 0xF00) >> 8;
	const int fourth_4 = (source & 0xF000) >> 12;

	cout << hex;
	cout << "Source           = 0x" << source << endl;
	cout << "First four bits  = 0x" << first_4 << endl;
	cout << "Second four bits = 0x" << second_4 << endl;
	cout << "Third four bits  = 0x" << third_4 << endl;
	cout << "Fourth four bits = 0x" << fourth_4 << endl;
	
    return 0;
}


Hope this helps,
Fredrik
 
Share this answer
 
Comments
Baakki 7-Nov-13 6:32am    
Thank u so much....
Fredrik Bornander 7-Nov-13 6:36am    
Glad I could help.
CPallini 7-Nov-13 15:13pm    
5.
Fredrik Bornander 8-Nov-13 2:54am    
Thank you, good sir!
As I can't believe no-one else's come up with this and everyone's been farting around with shifts, masks and unions:

C++
char least_significant_hex_digit( unsigned number )
{
     return number % 16;
}


To work out subsequent digits divide by 16 first:

C++
std::vector<char> split_into_hex_digits( unsigned number )
{
    std::vector<char> digits;
    for( ; number; number /= 16 )
    {
        digits.push_back( number % 16 );
    }
    return digits;
}</char></char>


With a decent optimiser it'll end up as fast as anything using shifts and potentially faster as most processors produce a remainder when doing a division which'll combine the divide and modulo.
 
Share this answer
 
Comments
Baakki 7-Nov-13 6:33am    
Thank u for ur valuable suggestion dude....
Kosta Cherry 7-Nov-13 10:49am    
The reason people use masks and shifts is that it is much, much faster than a division. You may hope that optimiser will convert your div to shift or a mask, but why not to do the right thing to begin with, rather than hope that someone will correct you?

From here (http://en.wikibooks.org/wiki/Optimizing_C%2B%2B/Code_optimization/Faster_operations):

"The multiplication, division, and modulo operations between integer numbers are much faster if the second operand is a constant power of two, as in such case they are implemented as bit shifts or bit maskings."
Aescleal 7-Nov-13 11:56am    
"much, much faster"? Really? I tested the code on Microsoft's x86 compiler (every version from 1.52 to 2010) and divison/modulus was within 1% of the performance of the shift. I also tested on gcc 3.3, 4.1 and 4.8 for both x86 and ARM and there was no difference. The assembler generated was just about identical between compilers as well. Performance didn't change much when I converted the vector to a built in array in case the dastardly STL implementation was slowing things down and reducing the impact of me begging the compiler to do its job properly.

Unrolling the loop didn't do anything for the speed either.

Even when using an unoptimised version the compilers couldn't stop themselves and were doing shifts instead of division (MS's still did a div for the modulo though). And the performance wasn't that different from the optimised version.

So I'll trust my compilers to convert from the direct statement of an algorithm to whatever arcana the silicon wants.

The moral of this story is messing about with premature optimisation is pointless unless you know you have a performance issue. Write your code to represent what you want it to do and if that's not fast enough then start thinking about micro-optimisations.

[edit for wonky English...]
Kosta Cherry 7-Nov-13 13:18pm    
Yes, really. From your own answer: "The assembler generated was just about identical". And this is exacly the case I pointed out (see my original reply): "as in such case they are implemented as bit shifts or bit maskings". Division is optimised in one, and only one case: "if the second operand is a constant power of two". If you take a habit of mindlessly using division, you are bound to a case when second operand is NOT a power of two, and performance drains down. It's not a premature optimisation, it's a habit of writing code that is optimised from the beginning, instead of brute force approach and hope that compiler writers foresaw your case. The best solution here (performance wise) was a union trick. Premature optimisation? Nope, just a good code to begin with, and experienced programmer who "been there, done that".
CPallini 7-Nov-13 15:13pm    
My 5.
You could use the union trick:
C++
#include <iostream>
#include <cstdint>
using namespace std;

union Nibble
{
    uint16_t u16;
    struct
    {
        unsigned int n0 :4;
        unsigned int n1 :4;
        unsigned int n2 :4;
        unsigned int n3 :4;
    } nb;
};

int main ()
{
    uint16_t n = 0x156A;

    Nibble nibble;
    nibble.u16 = n;
    cout << nibble.nb.n0 << ", " <<  nibble.nb.n1 << ", " << nibble.nb.n2 << ", " <<  nibble.nb.n3 << ", " << endl;
}
 
Share this answer
 
Comments
Baakki 7-Nov-13 6:34am    
Thank u for ur valuable suggestion dude....
CPallini 7-Nov-13 15:14pm    
You are welcome.
Aescleal 7-Nov-13 6:38am    
Have a 5 (at least when I work out how to change the 4 I clicked on by accident just now) to balance the 1 someone else dispensed. While I wouldn't have done it this way it's a valid alternative to the shift and mask solutions proposed before it.
CPallini 7-Nov-13 15:12pm    
Thank you.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900