Exercise using: unsigned char bcd(int n);

Please support our C advertiser: Programming Forums - DaniWeb Sister Site
Reply

Join Date: Sep 2004
Posts: 421
Reputation: JoBe is on a distinguished road 
Solved Threads: 4
JoBe's Avatar
JoBe JoBe is offline Offline
Posting Pro in Training

Re: Exercise using: unsigned char bcd(int n);

 
0
  #11
Mar 31st, 2005
>Not totally I hope.
That was my intention yes, but then again, I do like to try and learn this, it's just so frustrating that even when getting help from you and Dave, I STILL can't figure it out :!:

>
  1. while ( value != 0 )
  2. {
  3. cout<< !!( value & 1 );
  4. value >>= 1;
  5. }
When I try this with the value 12345, I get this as a binary code: 10011100000011
Tough, the code should be 0001 0010 0011 0100 0101

>12345 -> 0001 0010 0011 0100 0101
I understand that the decimal value equals this binary code, the problem is, how in the h*ll do I get (0100 0101) into a return value (unsigned char) :mad:
Reply With Quote Quick reply to this message  
Join Date: Apr 2004
Posts: 4,413
Reputation: Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future Dave Sinkula has a brilliant future 
Solved Threads: 248
Team Colleague
Dave Sinkula's Avatar
Dave Sinkula Dave Sinkula is offline Offline
long time no c

Re: Exercise using: unsigned char bcd(int n);

 
0
  #12
Mar 31st, 2005
Originally Posted by JoBe
>12345 -> 0001 0010 0011 0100 0101
I understand that the decimal value equals this binary code
The left is not the same value as the right.

Perhaps some debugging printfs can help.
#include <stdio.h>

unsigned int dec2bcd(unsigned int dec)
{
   unsigned int bits, bcd = 0;
   for ( bits = 0; dec; bits += 4, dec /= 10 )
   {
      printf("dec = %5u, bits = %2u, bcd = %6u (0x%04x)\n", dec, bits, bcd, bcd);
      bcd |= dec % 10 << bits;
   }
   return bcd;
}

int main()
{
   unsigned int value = 12345, result = dec2bcd(value);
   printf("bcd(%u) = 0x%X [%u]\n", value, result, result);
   return 0;
}

/* my output
dec = 12345, bits =  0, bcd =      0 (0x0000)
dec =  1234, bits =  4, bcd =      5 (0x0005)
dec =   123, bits =  8, bcd =     69 (0x0045)
dec =    12, bits = 12, bcd =    837 (0x0345)
dec =     1, bits = 16, bcd =   9029 (0x2345)
bcd(12345) = 0x12345 [74565]
*/
"One of the methods used by statists to destroy capitalism consists in establishing controls that tie a given industry hand and foot, making it unable to solve its problems, then declaring that freedom has failed and stronger controls are necessary." --Ayn Rand
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,783
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 745
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: Exercise using: unsigned char bcd(int n);

 
0
  #13
Mar 31st, 2005
>I STILL can't figure it out
Binary is a bitch to understand at first. This has nothing to do with your ability, it's a difficult subject for anyone to wrap their mind around when they first start working with.

>When I try this with the value 12345, I get this as a binary code: 10011100000011
That loop only prints the bits of a value. Unless 12345 has already been binary coded, you should expect 11000000111001, which because the loop prints the bits in reverse order, gives you 10011100000011. You're still confusing things:

12 = 1100

This is a binary value that is directly equivalent to the integral value 12. Notice how the value 12 fits in 4 bits. My loop prints this.

12 = 00010010

This is a binary encoding of the two integral digits 1 and 2. Notice how there's no way to fit this encoding in 4 bits, so 8 bits are used. Your bcd function returns this.

>how in the h*ll do I get (0100 0101) into a return value (unsigned char)
Return the integral value 69. 69 has the bit pattern 01000101, which is what you want and why I said this is a bit packing exercise.
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 421
Reputation: JoBe is on a distinguished road 
Solved Threads: 4
JoBe's Avatar
JoBe JoBe is offline Offline
Posting Pro in Training

Re: Exercise using: unsigned char bcd(int n);

 
0
  #14
Apr 1st, 2005
Well, after the additional tips you gave, I got to the point that I'm getting an output of 1010001, apparantly, I'm still missing one 0 at the back :-|

THe code I used was this:
  1. int main()
  2. {
  3. int value = 12345;
  4. char x;
  5.  
  6. x = bcd(value);
  7.  
  8. while ( x != 0 )
  9. {
  10. cout<< !!( x & 1 );
  11. x >>= 1;
  12. }
  13.  
  14. return 0;
  15. }
  16.  
  17. unsigned char bcd (int n)
  18. {
  19.  
  20. if ( n >= 10 )
  21. {
  22. int a = n % 10;
  23. int b = ( n / 10 ) % 10;
  24.  
  25. return ( b << 4 ) | a;
  26. }
  27.  
  28. return n;
  29. }

So, all I have to do know is reverse the value 1010001 into '0'100 0101, correct

Also, could you explain how this piece of code works:
  1. !!( x & 1 )

>12 = 1100
I understand this Narue, because four bits can have a maxim value of 15, wich also equals the amount in hex from 0 to 9 and A to F.

>12 = 00010010
This however I don't understand I mean, I understand it to be eight bits

@ Dave,
Thanks for the additional info, however I didn't try out the code you wrote because I feared I would get even more confuzed then I allready am :!:

I did include the link you gave me into my favorites and will read the article later on, thanks for that :!:
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,783
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 745
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: Exercise using: unsigned char bcd(int n);

 
0
  #15
Apr 1st, 2005
>Also, could you explain how this piece of code works
x & 1 lets you access the low order bit of x. The double bang trick guarantees that the resulting value is normalized to 0 or 1. Figuring it out is a fun exercise, try taking away one !, then take away the other. Try using something other than 1 for the right hand side of the & and do the same thing.

>I mean, I understand it to be eight bits
Then you understand without understanding it seems. Yes, it is eight bits, because you're taking each digit of the original number (12, or 1 and 2, or 0001 and 0010) setting aside four bits for each of them, and then pasting those four bit chunks together to get the binary code, 00010010.
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 421
Reputation: JoBe is on a distinguished road 
Solved Threads: 4
JoBe's Avatar
JoBe JoBe is offline Offline
Posting Pro in Training

Re: Exercise using: unsigned char bcd(int n);

 
0
  #16
Apr 3rd, 2005
Nope, not working :!:

When I use this code:
  1. #include <iostream>
  2. #include <sstream>
  3. #include <string>
  4.  
  5. using namespace std;
  6.  
  7. unsigned char bcd (int n);
  8.  
  9. int main()
  10. {
  11. int value = 12;
  12. char x;
  13.  
  14. x = bcd(value);
  15.  
  16. while ( x != 0 )
  17. {
  18. cout<< !!( x & 1 );
  19. x >>= 1;
  20. }
  21.  
  22. return 0;
  23. }
  24.  
  25. unsigned char bcd (int n)
  26. {
  27.  
  28. if ( n >= 10 )
  29. {
  30. int a = n % 10;
  31. int b = ( n / 10 ) % 10;
  32. return ( b << 4 ) | a;
  33. }
  34.  
  35. return n;
  36. }

My result is this binary code: 01001 :o When it should be 0001 0010 :rolleyes:

I tried out using
  1. !( x & 1 );
I tried out using
  1. ( x & 1 );
I tried out using
  1. !!( x & 2 );
I tried out ... several other changes in this piece of code, they all gave different outcomes, but to be honest, I don't know WHY it happend and I don't know why or when I would use these changes because I don't know what happens with the code

I also changed this
  1. return ( b << 4 ) | c;
into this
  1. return ( a << 4 ) | b;
wich actually returned this: 100001
Why, I have no idea

So, to make it short, after all tries and tribulations I still haven't found the solution to my exercise :!:

DARN
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,783
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 745
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: Exercise using: unsigned char bcd(int n);

 
0
  #17
Apr 3rd, 2005
>Nope, not working
It's working fine, just not the way you want it to.

>My result is this binary code: 01001 When it should be 0001 0010
Okay, reverse what you got because the loop prints the low-order bits first:

10010

Now notice the condition for the printing loop, while x != 0. Because the loop only prints as long as there's a 1 bit somewhere in the value, leading 0's are ignored. So you're getting the correct output, it's just not formatted as you expected.

To be perfectly honest, that method of printing bits only has the advantage of being simple to write correctly the first time. Another easy (if incredibly obscure) way to print the bits properly is with bitset:
  1. #include <bitset>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. unsigned char bcd (int n);
  7.  
  8. int main()
  9. {
  10. int value = 12345;
  11. unsigned char x;
  12.  
  13. x = bcd(value);
  14. cout<< bitset<8> ( x ).to_string<char, char_traits<char>, allocator<char> >() <<endl;
  15.  
  16. return 0;
  17. }
  18.  
  19. unsigned char bcd (int n)
  20. {
  21.  
  22. if ( n >= 10 )
  23. {
  24. int a = n % 10;
  25. int b = ( n / 10 ) % 10;
  26.  
  27. return ( b << 4 ) | a;
  28. }
  29.  
  30. return n;
  31. }
You can do it manually without the aid of the standard library like so:
  1. #include <bitset>
  2. #include <iostream>
  3.  
  4. using namespace std;
  5.  
  6. unsigned char bcd (int n);
  7.  
  8. int main()
  9. {
  10. int value = 12345;
  11. unsigned char x;
  12.  
  13. x = bcd(value);
  14. for ( int i = 7; i >= 0; i-- )
  15. cout<< !!( x & ( 1U << i ) );
  16.  
  17. return 0;
  18. }
  19.  
  20. unsigned char bcd (int n)
  21. {
  22.  
  23. if ( n >= 10 )
  24. {
  25. int a = n % 10;
  26. int b = ( n / 10 ) % 10;
  27.  
  28. return ( b << 4 ) | a;
  29. }
  30.  
  31. return n;
  32. }
But for the usual reasons, that's not as good of a solution.
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 421
Reputation: JoBe is on a distinguished road 
Solved Threads: 4
JoBe's Avatar
JoBe JoBe is offline Offline
Posting Pro in Training

Re: Exercise using: unsigned char bcd(int n);

 
0
  #18
Apr 3rd, 2005
[HOMER] DOH :!: [/HOMER]

Oh Narue, why do you allways make it look so simple :mrgreen:

>
  1. cout<< !!( x & ( 1U << i ) );

I understand '!!' being used to make sure that only 0 or 1 are shown.

Like in the previous thread, you said that x & 1 was used for accessing the lower bit, but why is there U mentioned behind it

>But for the usual reasons, that's not as good of a solution.
Why is the other solution better then

Anyway, thanks for the help
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,783
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 745
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: Exercise using: unsigned char bcd(int n);

 
0
  #19
Apr 3rd, 2005
>Oh Narue, why do you allways make it look so simple
As you gain experience, hard things become simple and impossible things become hard.

>why is there U mentioned behind it
Force of habit. It's always a good idea to force all parts of a bitwise expression to unsigned types because the bitwise operators are surprisingly tricky to use with signed types. 1U basically says that 1 is an unsigned int rather than a signed int.

>Why is the other solution better then
The usual suspects:

1) Portability (the same code will work the same everywhere)
2) Reuse (you don't have to solve the same problems over and over)
3) Performance (the standard library is written to be fast)
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:



Other Threads in the C Forum
Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC