gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > writing directly binary

#69710 - deltree - Wed Feb 01, 2006 2:13 pm

hi,
sorry about that beginner question again, it's about C and C++:
is it possible to write directly in binary on a variable ?
I know how to initialize a variable in hexa, but not binary.
how to do it ?

#69714 - tepples - Wed Feb 01, 2006 2:38 pm

C has no way to specify a literal constant in binary (base 2). It does have base 8 and base 16.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#69803 - Miked0801 - Thu Feb 02, 2006 12:31 am

foo = 01000101010b;

#69846 - keldon - Thu Feb 02, 2006 9:18 am

Miked0801 wrote:
foo = 01000101010b;

I did not know that. But since binary -> hex is so easy I (and most people who didn't know that) never cared anyway. But that will definately come in handy and make code much clearer now.

#69851 - Cearn - Thu Feb 02, 2006 10:17 am

keldon wrote:
Miked0801 wrote:
foo = 01000101010b;

I did not know that.

Neither did I. GCC (4.0.1) doesn't seem familiar with it either, all I get from that is
Quote:
error: invalid suffix "b" on integer constant
Can't find anything in its manual about it either. Are you sure it isn't just an extension of the compiler you're using?

#70660 - Miked0801 - Wed Feb 08, 2006 1:37 am

Truely? Hmmm - it was in my C book from way back (goes back and checks college text from way back.)

Well, well, well. It turns out I was remembering an old assembly book. In assembler, you can put h, o, b, d... on the end to change the base. My bad.

In C putting a 0 (zero) in front of a number tells the compiler it's octal, 0x for hex. Putting and l on the end of it is long, f - float, d = double, e = exponential (10e6 = 1 million). Nothing allows straight binary representation that I can see though.

#70661 - Miked0801 - Wed Feb 08, 2006 1:38 am

Which means you probably could "Inline asm" a db command with a b on the end for binary - but that's cheating...

#70667 - DekuTree64 - Wed Feb 08, 2006 2:34 am

Here's an ugly way to do it :)

Code:
#define BINARY_4BIT(b3,b2,b1,b0) ((b0)|((b1)<<1)|((b2)<<2)|((b3)<<3))
#define BINARY_BYTE(b7,b6,b5,b4,b3,b2,b1,b0) (BINARY_4BIT(b3,b2,b1,b0)|(BINARY_4BIT(b7,b6,b5,b4)<<4))

int one = BINARY_BYTE(0,0,0,0,0,0,0,1);

_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#70720 - kusma - Wed Feb 08, 2006 11:24 am

there exists some nasty template-tricks to do it in c++ aswell... not very pretty, though.

#70721 - sgeos - Wed Feb 08, 2006 11:27 am

Packed bit fields?

-Brendan

#70758 - deltree - Wed Feb 08, 2006 4:39 pm

well... I think i'll have to work on translating binary to hex mentally;

#70760 - naleksiev - Wed Feb 08, 2006 4:49 pm

Here you can find a lot of different solutions
http://www.flipcode.com/cgi-bin/fcarticles.cgi?show=63908

#70791 - Miked0801 - Wed Feb 08, 2006 8:03 pm

Trust me, being able to go back and forther from decimal to hex is a very necessary and useful skill to have. Once you do that, it's very simple to go from hex to binary and back. I'm to the point now where I can read many hex number without "translating" them in my head.

#70792 - kusma - Wed Feb 08, 2006 8:12 pm

sgeos wrote:
Packed bit fields?


the problem with that approach is that bitfields are allowed to be rearranged by the implementation.

#70796 - poslundc - Wed Feb 08, 2006 8:26 pm

Miked0801 wrote:
Trust me, being able to go back and forther from decimal to hex is a very necessary and useful skill to have. Once you do that, it's very simple to go from hex to binary and back. I'm to the point now where I can read many hex number without "translating" them in my head.


I agree with this statement. Hex is the new binary. Learn it, love it.

Dan.

#70911 - keldon - Thu Feb 09, 2006 3:14 pm

Try this:
Code:

#include<iostream>
using namespace std;

// Byte, shifted by n * 8
#define BN(b,n) (\
   ( \
      ( (b) & 1 ) | \
      ( (((b) >> 4) & 1 ) << 1 ) | \
      ( (((b) >> 8) & 1 ) << 2 ) | \
      ( (((b) >> 12) & 1 ) << 3 ) | \
      ( (((b) >> 16) & 1 ) << 4 ) | \
      ( (((b) >> 20) & 1 ) << 5 ) | \
      ( (((b) >> 24) & 1 ) << 6 ) | \
      ( (((b) >> 28) & 1 ) << 7 )\
   ) << (n) * 8 \
   )

// Byte
#define B(b) (\
   ( (b) & 1 ) | \
   ( (((b) >> 4) & 1 ) << 1 ) | \
   ( (((b) >> 8) & 1 ) << 2 ) | \
   ( (((b) >> 12) & 1 ) << 3 ) | \
   ( (((b) >> 16) & 1 ) << 4 ) | \
   ( (((b) >> 20) & 1 ) << 5 ) | \
   ( (((b) >> 24) & 1 ) << 6 ) | \
   ( (((b) >> 28) & 1 ) << 7 )\
   )

// Word
#define W(b1,b2) (\
   BN((b1),1) | BN((b2),0 ) \
   )

// Double Word
#define D(b1,b2,b3,b4) (\
   BN((b1),3) | BN((b2),2 ) | BN((b3),1 )  | BN((b4),0 ) \
   )


int main () {
   cout << B ( 0x11111111);               // prints 255
   cout << BN ( 0x1,1);                  // prints 256
   cout << D(0x0,0x0,0x1,0x0) << "\n";   // prints 256
   return 0;
}


D is basically 4 bytes, making a double word. BN allows you to shift by a number of bytes - which you can tell by the output of BN (0x1, 1). I have chosen hexadecimal numbers simply so that you can write B(0x00001000) for simplicity and readability.

I tried doing this using long long's, but my gcc compiler does not like '(long long)0x076543210', so I am guessing Devkit Pro will not either.

EDIT: Added Word, and changed BD to D. Word is untested, but should work

p.s. I would have liked to use DB and DW, from the asm conventions. But I don't think there is one for double words

#71411 - keldon - Sun Feb 12, 2006 6:51 pm

Okay, 16 bit binary values work now, using long longs.
Code:

#define LW(b) (\
   ( (b) & 1 ) | \
   ( (((b) >> 4) & 1 ) << 1 ) | \
   ( (((b) >> 8) & 1 ) << 2 ) | \
   ( (((b) >> 12) & 1 ) << 3 ) | \
   ( (((b) >> 16) & 1 ) << 4 ) | \
   ( (((b) >> 20) & 1 ) << 5 ) | \
   ( (((b) >> 24) & 1 ) << 6 ) | \
   ( (((b) >> 28) & 1 ) << 7 ) | \
   ( (((b) >> 32) & 1 ) << 8 ) | \
   ( (((b) >> 36) & 1 ) << 9 ) | \
   ( (((b) >> 40) & 1 ) << 10 ) | \
   ( (((b) >> 44) & 1 ) << 11 ) | \
   ( (((b) >> 48) & 1 ) << 12 ) | \
   ( (((b) >> 52) & 1 ) << 13 ) | \
   ( (((b) >> 56) & 1 ) << 14 ) | \
   ( (((b) >> 60) & 1 ) << 15 )\
   )
// ---

   //             HighByte LowByte
   //           --7654321076543210--
   cout << LW ( 0x1111111111111111LL ) << "\n";         // prints 65535
   cout << LW ( 0x0000000100000000LL ) << "\n";         // prints 256