>out<< n;
>string s = out.str();
In this case (since you're taking the rightmost digits) arithmetic operations may be easier:
if ( n >= 10 ) { // Make sure there are two digits
int a = n % 10;
int b = ( n / 10 ) % 10;
}
>how can I return two separate pieces of binary code
It's an exercise in bit packing. The two 4 bit chunks are packed together in an unsigned char:
( b << 4 ) | a
>3) Also, how can an unsigned char return a binary code 0100 0101?
The char type has to be at least 8 bits by definition, so you can easily fit two 4 bit pieces there.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>0xC0000005: Access Violation
An access violation means you tried to access memory outside of your address space. After debugging lots of these problems, you begin to get a sense for what memory addresses look "wrong" for what you're trying to do. 0xC0000005 looks wrong, and most likely one of your indices is accessing an array out of bounds.
Of course, your solution is way too long. You could practically paste the code I gave you into your function body and be set:
unsigned char bcd ( int n )
{
if ( n >= 10 ) { // Make sure there are two digits
int a = n % 10;
int b = ( n / 10 ) % 10;
return ( b << 4 ) | a;
}
return n;
}
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>but using it solely doesn't make the decimal number into a binary code
The binary code is packed inside an unsigned char. The only way to get it out is to access the value bit by bit:
while ( value != 0 ) {
cout<< !!( value & 1 );
value >>= 1;
}
You're confusing a binary code with the string representation of a binary code.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
I was under the impression that the return value might be expected to be an unsigned int, and that the expected input/output might be as follows.
#include <stdio.h>
unsigned int dec2bcd(unsigned int dec)
{
unsigned int bits, bcd = 0;
for ( bits = 0; dec; bits += 4, dec /= 10 )
{
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
bcd(12345) = 0x12345 [74565]
*/
Or am I just off today?
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
>but I'm giving up on this
Not totally I hope. You've shown a lot of promise. Programming is hard. There's no getting around it, so you just have to keep going until you finally have a flash of insight and understand what was confusing you. Then you can move on to a new thing that confuses you. This process is repeated until you die.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
>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 debuggingprintfs 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]
*/
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
>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.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>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.
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>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:
#include <bitset>
#include <iostream>
using namespace std;
unsigned char bcd (int n);
int main()
{
int value = 12345;
unsigned char x;
x = bcd(value);
cout<< bitset<8> ( x ).to_string<char, char_traits<char>, allocator<char> >() <<endl;
return 0;
}
unsigned char bcd (int n)
{
if ( n >= 10 )
{
int a = n % 10;
int b = ( n / 10 ) % 10;
return ( b << 4 ) | a;
}
return n;
}
You can do it manually without the aid of the standard library like so:
#include <bitset>
#include <iostream>
using namespace std;
unsigned char bcd (int n);
int main()
{
int value = 12345;
unsigned char x;
x = bcd(value);
for ( int i = 7; i >= 0; i-- )
cout<< !!( x & ( 1U << i ) );
return 0;
}
unsigned char bcd (int n)
{
if ( n >= 10 )
{
int a = n % 10;
int b = ( n / 10 ) % 10;
return ( b << 4 ) | a;
}
return n;
}
But for the usual reasons, that's not as good of a solution. :)
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
>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)
Narue
Bad Cop
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401