byte,char exactly 8 bits?

Started by
26 comments, last by GameDev.net 18 years ago
Bah, more type safety is often a good thing:

struct byte {  typedef unsigned char value_type;  value_type v;  byte(const byte&b):v(b.v){};  explicit byte(const unsigned char v_):v(v_){};  void swap(byte&b) {std::swap(v, b.v);};  value_type value() {return v;}  bool iszero() {return !v;}  byte& operator=(const byte&b) {byte tmp = b; swap(tmp); return *this;}  bool operator==(const byte&b) const {return v==b.v;};  bool operator!=(const byte&b) const {return v!=b.v;};  bool operator<=(const byte&b) const {return v<=b.v;};  bool operator>=(const byte&b) const {return v>=b.v;};  bool operator< (const byte&b) const {return v< b.v;};  bool operator> (const byte&b) const {return v> b.v;};  byte operator| (const byte&b) const {return byte(v|b.v);};  byte operator& (const byte&b) const {return byte(v&b.v);};  byte operator^ (const byte&b) const {return byte(v^b.v);};  byte&operator|=(const byte&b)       {return *this=(*this|b);}  byte&operator&=(const byte&b)       {return *this=(*this&b);}  byte&operator^=(const byte&b)       {return *this=(*this^b);}  byte operator~ ()             const {return byte(~v);};  byte operator<<(int a)        const {return byte(v<<a);};  byte operator>>(int a)        const {return byte(v>>a);};};


A byte class that takes the same storage as an unsigned char that should be reduced by any decent optimizer to being just an unsigned char -- but is type incompatable with unsigned chars.
Advertisement
Quote:Original post by extralongpants
Just to re-iterate, the real problem with your code is as the Anonymous Poster said - a char will only hold values from -128 to +127, while an unsigned char will hold values from 0-255. Thus, in this instance, you should be using an unsigned char.

You should also explicitly type-cast as Date Hunt suggested.


Whether a char is signed or unsigned is implementation defined. If you are using a char for numerical (as opposed to character) data then you should specify signed char or unsigned char. Note also that char is a distinct type and is neither a signed char nor an unsigned char, although its representation will be identical to one of them.

Σnigma

[Edited by - Enigma on April 5, 2006 10:09:57 AM]
Quote:Original post by Enigma
Quote:Original post by extralongpants
Just to re-iterate, the real problem with your code is as the Anonymous Poster said - a char will only hold values from -128 to +127, while an unsigned char will hold values from 0-255. Thus, in this instance, you should be using an unsigned char.

You should also explicitly type-cast as Date Hunt suggested.


Whether a char is signed or unsigned is implementation defined. If you are using a char for numerical (as opposed to character) data then you should specify signed char or unsigned char. Note also that char is a distict type and is neither a signed char nor an unsigned char, although its representation will be identical to one of them.

Σnigma


Thanks for the clarification. I wasn't actually aware that a char was not inherently signed or unsigned. It makes sense though.

Quote:Original post by NotAYakk
Bah, more type safety is often a good thing:

struct byte {  typedef unsigned char value_type;  value_type v;  byte(const byte&b):v(b.v){};  explicit byte(const unsigned char v_):v(v_){};  void swap(byte&b) {std::swap(v, b.v);};  value_type value() {return v;}  bool iszero() {return !v;}  byte& operator=(const byte&b) {byte tmp = b; swap(tmp); return *this;}  bool operator==(const byte&b) const {return v==b.v;};  bool operator!=(const byte&b) const {return v!=b.v;};  bool operator<=(const byte&b) const {return v<=b.v;};  bool operator>=(const byte&b) const {return v>=b.v;};  bool operator< (const byte&b) const {return v< b.v;};  bool operator> (const byte&b) const {return v> b.v;};  byte operator| (const byte&b) const {return byte(v|b.v);};  byte operator& (const byte&b) const {return byte(v&b.v);};  byte operator^ (const byte&b) const {return byte(v^b.v);};  byte&operator|=(const byte&b)       {return *this=(*this|b);}  byte&operator&=(const byte&b)       {return *this=(*this&b);}  byte&operator^=(const byte&b)       {return *this=(*this^b);}  byte operator~ ()             const {return byte(~v);};  byte operator<<(int a)        const {return byte(v<<a);};  byte operator>>(int a)        const {return byte(v>>a);};};


A byte class that takes the same storage as an unsigned char that should be reduced by any decent optimizer to being just an unsigned char -- but is type incompatable with unsigned chars.


Where is the subtraction,addition,multiplication,and division overloads?
----------------------------

http://djoubert.co.uk
The standard specifies that char objects must always be at _least_ 8 bits long, though they can always be more.
You can use "__int8" or "unsigned __int8".
MSDN Link.
Quote:Original post by Kambiz
You can use "__int8" or "unsigned __int8".
MSDN Link.


Which, unfortunately (or fortunately), only works on Microsoft's compilers.
Quote:Original post by dawidjoubert
Quote:Original post by NotAYakk
Bah, more type safety is often a good thing:

struct byte {  typedef unsigned char value_type;  value_type v;  byte(const byte&b):v(b.v){};  explicit byte(const unsigned char v_):v(v_){};  void swap(byte&b) {std::swap(v, b.v);};  value_type value() {return v;}  bool iszero() {return !v;}  byte& operator=(const byte&b) {byte tmp = b; swap(tmp); return *this;}  bool operator==(const byte&b) const {return v==b.v;};  bool operator!=(const byte&b) const {return v!=b.v;};  bool operator<=(const byte&b) const {return v<=b.v;};  bool operator>=(const byte&b) const {return v>=b.v;};  bool operator< (const byte&b) const {return v< b.v;};  bool operator> (const byte&b) const {return v> b.v;};  byte operator| (const byte&b) const {return byte(v|b.v);};  byte operator& (const byte&b) const {return byte(v&b.v);};  byte operator^ (const byte&b) const {return byte(v^b.v);};  byte&operator|=(const byte&b)       {return *this=(*this|b);}  byte&operator&=(const byte&b)       {return *this=(*this&b);}  byte&operator^=(const byte&b)       {return *this=(*this^b);}  byte operator~ ()             const {return byte(~v);};  byte operator<<(int a)        const {return byte(v<<a);};  byte operator>>(int a)        const {return byte(v>>a);};};


A byte class that takes the same storage as an unsigned char that should be reduced by any decent optimizer to being just an unsigned char -- but is type incompatable with unsigned chars.


Where is the subtraction,addition,multiplication,and division overloads?


And >>=, <<=, and - (negate, not subract) ?
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Quote:Original post by smart_idiot
Quote:Original post by dawidjoubert

Where is the subtraction,addition,multiplication,and division overloads?


And >>=, <<=, and - (negate, not subract) ?


I forgot >>= and <<=. Ooops. =) Serves me right for doing whole-cloth coding in a forum.

I would assume that byte as a type are raw binary data (not 8 bit integers), so I would actually be against having +,-,/,*.

But if you just want a strong_typedef, implement:
template<typename data, typename tag_type>struct strong_typedef { /* boilerplate code here */ };struct byte_tag;typedef strong_typedef<unsigned char, byte_tag*> byte;


strong_typedef would act like the above byte class (no implicit casts).

The tag_type would be unused anywhere in the implementation -- it's purpose is to make the typedef strong.

You'd also want to implement raw() non-member methods (that just call value()).

Random:
why doesn't C++ have an
operator===
;)

PS: I also forgot the trivial constructor. =)
char is defaulting to signed, meaning it is between -128 and +127.
So yes 254 is overflowing that.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

This topic is closed to new replies.

Advertisement