15

I have programmed a class called HugeInteger which can do arithmetic (add, sub, multiply) with numbers of "infinitely" size. It treats each bit of the digit in the number as a stand-alone digit (e.g. 1234 = 1, 2, 3 and 4). I store these numbers in a vector (vector<short>). Now, because each digit only can take the values from 0 to 9, i don't really need to store them as a 2 byte digit. Is there a way (without using char) to store the digits as a 1 byte unsigned integer? Thanks!

Update:

vector<unsigned char> v;
v.push_back(1);
v.push_back(2);

for (size_t i = 0; i < v.size(); i++)
    cout << v[i];

This produces an unwanted output. Which datatype should I use to iterate through the vector?

raze
  • 662
  • 3
  • 8
  • 25
  • 1
    The header provides a type named "uint8_t" - if your environment supports such a type. Please note that "uint8_t" can be a typedef for 'unsigned char'. So overloading might not work as expected in all cases. – nosid Apr 01 '12 at 17:47
  • 3
    `unsigned char` is C++'s "one byte unsigned integer" by definition. Why don't you want a solution to your problem? – R. Martinho Fernandes Apr 01 '12 at 17:47
  • @jwodder: I don't know the intentions of the OP, but `char` is not necessarily `unsigned`. This may cause portability issues for values outside [0, 127] – Matthieu M. Apr 01 '12 at 17:51
  • The OP says values from 0 to 9. – Mr Lister Apr 01 '12 at 17:53
  • I stand corrected. I didn't know that you could do something like this: vector v; v.push_back(1); v.push_back(2); int a = a[0] + a[1]; – raze Apr 01 '12 at 17:53
  • 2
    No, you can't do `a = a[0] + a[1];`, believe me. – Mr Lister Apr 01 '12 at 17:55
  • @R.MartinhoFernandes: No, it isn't necessarily one byte. Don't confuse `sizeof (char)` (always 1) with size in bytes. `sizeof` returns the size in units of `char`, not bytes. – Ben Voigt Apr 01 '12 at 18:07
  • @BenVoigt units of `char` are bytes by definition (cf. §1.7p1). Don't confuse byte with 8 bits. – R. Martinho Fernandes Apr 01 '12 at 18:14
  • @R.MartinhoFernandes: No, the size of a byte is architecture dependent, but it may not be enough for a `char`. There are systems with 6 or 7 bit bytes. Such bytes are not large enough to hold the range of values required for `char` -- on such systems a `char` is more than one byte (and `sizeof (T)` does not return the number of bytes). – Ben Voigt Apr 01 '12 at 18:20
  • @Ben hmm, [chat](http://chat.stackoverflow.com/rooms/10/loungec)? (Check §5.3.3p1, btw) – R. Martinho Fernandes Apr 01 '12 at 18:22
  • By the way, the unwanted output is because you need to cast to int when passing to a stream, unless you really want to avoid that, but the unsigned char is precisely what you want – SirGuy Apr 01 '12 at 21:12
  • What if you wanted to output a number, though? – ArtOfWarfare Jan 20 '13 at 21:22
  • This is late, but you can use a bit field if you want. – noɥʇʎԀʎzɐɹƆ Jun 10 '16 at 19:03

5 Answers5

29

Yes, use unsigned char.

If <stdint.h> is available, then you could also use uint8_t.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • 1
    `uint8_t` is either one byte or a compile error. `unsigned char` may be larger than one byte (but only on systems where `uint8_t` is a compile error). – Ben Voigt Apr 01 '12 at 18:09
  • 2
    @Ben: `unsigned char` is always a "byte", but in C/C++ parlance, that "byte" may be more than 8 bits (though usually only on architectures that are considered unusual by today's standards). – Ken Bloom Apr 01 '12 at 18:21
13

Don't let the standard compiler type char confuse you; the following is perfectly legal:

char number[5] = { 1, 4, 3, 6, 2};   // Representation of decimal 14,362

It's not that there is anything special about the char type that forces you to think of them as characters; rather, it's is their convenient size of just 1 byte that makes them suitable to hold values that library routines such as printf use them to hold the 1-byte values that it will interpret as characters under a suitable encoding.

chepner
  • 497,756
  • 71
  • 530
  • 681
  • 1
    Yeah, this was new to me. I though that I needed single-quotes around every char. Thanks for the tip! – raze Apr 01 '12 at 18:00
2

uint_least8_t is the most compact data type for storing a single decimal digit.

If your system supports a data type of size 1 byte, this will be it. Otherwise it will be the next smallest data type available.

You may need to cast the value when using a stream insertion operator to make sure you get numeric output instead of character treatment.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

The output you're seeing from using cout << on an unsigned char is down to the mechanics of the << operator when used with a std::ostream (specifically, different overloads of the operator << will display the value in different ways - the char/unsigned char overloads usually assume that you want a character representation instead of a numeric one)

The underlying representation of your unsigned char is still the same number which you pushed into the vector - an unsigned char is still an unsigned 1-byte integer)

If you wish to change the output, then you need to avoid using the overload of the << operator which is designed for char or unsigned char - the easiest way to do that is to perform a cast

vector<unsigned char> v;
v.push_back(1);
v.push_back(2);

for (size_t i = 0; i < v.size(); i++)
    cout << static_cast<int>( v[i] );
Ben Cottrell
  • 5,741
  • 1
  • 27
  • 34
0

Using char or unsigned char as 1 byte integer type is not always that straightforward... Sometimes you just need the type to be number type, not character type. One such example is here: 1 byte integer data type Other is when you have function overloaded for arguments of several different types.

Community
  • 1
  • 1
Telvas
  • 158
  • 8