sorry for the stupid question, but how would I go about figuring out, mathematically or using c++, how many bytes it would take to store an integer.
-
5`int HowManyBytesToStoreAnInteger() { return sizeof(int); }` Or did you mean something else? – Robᵩ Mar 17 '11 at 02:41
-
possible duplicate of [How to determine how many bytes an integer needs?](http://stackoverflow.com/questions/2274428/how-to-determine-how-many-bytes-an-integer-needs) – Thomi Mar 17 '11 at 02:45
-
@rob I meant if you were given a number (say 700) how many bytes would you need to store that number (2). – Anonymous Mar 17 '11 at 02:46
-
What exactly do you mean? How many bytes does it take to store any value from 0 to N? Any value from -N to N? To represent a number N in a way so that the bytes can be uniquely converted back to the number N? Are the four bytes `{0, 0, 0, 1}` different from the two bytes `{0, 1}`? etc. – aschepler Mar 17 '11 at 02:48
-
What do you want the `sizeof(int)` does not provide? – chux - Reinstate Monica Oct 10 '20 at 21:02
11 Answers
If you mean from an information theory point of view, then the easy answer is:
log(number) / log(2)
(It doesn't matter if those are natural, binary, or common logarithms, because of the division by log(2), which calculates the logarithm with base 2.)
This reports the number of bits necessary to store your number.
If you're interested in how much memory is required for the efficient or usual encoding of your number in a specific language or environment, you'll need to do some research. :)
The typical C and C++ ranges for integers are:
char 1 byte
short 2 bytes
int 4 bytes
long 8 bytes
If you're interested in arbitrary-sized integers, special libraries are available, and every library will have its own internal storage mechanism, but they'll typically store numbers via 4- or 8- byte chunks up to the size of the number.
- 102,305
- 22
- 181
- 238
-
2almost - you need to round up to the nearest multiple of 8, since he asked for how many bytes – Martin DeMello Mar 17 '11 at 10:26
-
`log(number)` has trouble with `number <= 0`. Why use `log(number) / log(2)` at that has trouble with values near powers of 2: `log(number)` and `log(2)` only provides approximately correct answers. Seems better to use `log2(number)` instead. – chux - Reinstate Monica Oct 10 '20 at 21:07
-
@chux-ReinstateMonica it depends on the tools you've got available to you; some systems have base 10 and base e logs but not base 2 logs. There's lots of tools available if you don't have any of these to work with: https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogObvious – sarnold Oct 14 '20 at 00:37
You could find the first power of 2 that's larger than your number, and divide that power by 8, then round the number up to the nearest integer. So for 1000, the power of 2 is 1024 or 2^10; divide 10 by 8 to get 1.25, and round up to 2. You need two bytes to hold 1000!
- 80,601
- 10
- 150
- 186
-
You can even convert to binary and check how many bits or bytes it can take – Naruto Apr 11 '12 at 08:12
-
"first power of 2 that's larger than your number" has trouble for values near `INT_MAX` and `i < 0`. – chux - Reinstate Monica Oct 10 '20 at 21:03
If you mean "how large is an int" then sizeof(int) is the answer.
If you mean "how small a type can I use to store values of this magnitude" then that's a bit more complex. If you already have the value in integer form, then presumably it fits in 4, 3, 2, or 1 bytes. For unsigned values, if it's 16777216 or over you need 4 bytes, 65536-16777216 requires 3 bytes, 256-65535 needs 2, and 0-255 fits in 1 byte. The formula for this comes from the fact that each byte can hold 8 bits, and each bit holds 2 digits, so 1 byte holds 2^8 values, ie. 256 (but starting at 0, so 0-255). 2 bytes therefore holds 2^16 values, ie. 65536, and so on.
You can generalise that beyond the normal 4 bytes used for a typical int if you like. If you need to accommodate signed integers as well as unsigned, bear in mind that 1 bit is effectively used to store whether it is positive or negative, so the magnitude is 1 power of 2 less.
You can calculate the number of bits you need iteratively from an integer by dividing it by two and discarding the remainder. Each division you can make and still have a non-zero value means you have one more bit of data in use - and every 8 bits you're using means 1 byte.
A quick way of calculating this is to use the shift right function and compare the result against zero.
int value = 23534; // or whatever
int bits = 0;
while (value)
{
value >> 1;
++bits;
}
std::cout << "Bits used = " << bits << std::endl;
std::cout << "Bytes used = " << (bits / 8) + 1 << std::endl;
- 18,290
- 7
- 46
- 74
-
-
2
-
Voted up for accuracy Sharptooth, although I'd hope that anybody writing C++ on a system that doesn't have an 8 bit char already knows how to calculate this sort of thing. :) – Kylotan Mar 17 '11 at 13:11
This is basically the same question as "how many binary digits would it take to store a number x?" All you need is the logarithm.
A n-bit integer can store numbers up to 2n-1. So, given a number x, ceil(log2 x) gets you the number of digits you need.
It's exactly the same thing as figuring out how many decimal digits you need to write a number by hand. For example, log10 123456 = 5.09151220... , so ceil( log10(123456) ) = 6, six digits.
- 40,496
- 12
- 101
- 170
Since nobody put up the simplest code that works yet, I mind as well do it:
unsigned int get_number_of_bytes_needed(unsigned int N) {
unsigned int bytes = 0;
while(N) {
N >>= 8;
++bytes;
};
return bytes;
};
- 18,174
- 6
- 36
- 52
-
-
I one thinks `get_number_of_bytes_needed(0)`should return 1, a `do {.... while while(N);` will handle that. – chux - Reinstate Monica Oct 14 '20 at 02:37
The shortest code way to do this is as follows:
int bytes = (int)Math.Log(num, 256) + 1;
The code is small enough to be inlined, which helps offset the "slow" FP code. Also, there are no branches, which can be expensive.
- 17,747
- 20
- 91
- 154
-
Wouldn't +1 and floor sometimes, in the case that the log produces a whole number) result in an over-generous result? Ceiling is the more correct operation, no? e.g. int bytes = (int)Math.Ceiling(Math.Log(num, 256)); – N8allan Jun 20 '14 at 18:28
-
1Nope, it's correct. You can test it in Excel or via code. E.g. Log(256,256) = 1, with +1 = 2, which is correct. Log (255, 256) is ~0.99 = 0 + 1 = 1, which is correct. – IamIC Jun 21 '14 at 08:00
assuming sizeof(long int) = 4.
int nbytes( long int x )
{
unsigned long int n = (unsigned long int) x;
if (n <= 0xFFFF)
{
if (n <= 0xFF) return 1;
else return 2;
}
else
{
if (n <= 0xFFFFFF) return 3;
else return 4;
}
}
- 5,113
- 2
- 27
- 41
This code runs at 447 million tests / sec on my laptop where i = 1 to 1E9. i is a signed int:
n = (i > 0xffffff || i < 0) ? 4 : (i < 0xffff) ? (i < 0xff) ? 1 : 2 : 3;
- 17,747
- 20
- 91
- 154
/**
* assumes i is non-negative.
* note that this returns 0 for 0, when perhaps it should be special cased?
*/
int numberOfBytesForNumber(int i) {
int bytes = 0;
int div = 1;
while(i / div) {
bytes++;
div *= 256;
}
if(i % 8 == 0) return bytes;
return bytes + 1;
}
- 81,495
- 25
- 153
- 204
-
This is incorrect. For example, 1024/256 is 4, exactly, but the correct answer is 2. – Ernest Friedman-Hill Mar 17 '11 at 03:12
-
@Ernest thanks - fixed (i think, i'm in a dungeon right now, can't check it haha). – corsiKa Mar 17 '11 at 04:10
Try this code:
// works for num >= 0
int numberOfBytesForNumber(int num) {
if (num < 0)
return 0;
else if (num == 0)
return 1;
else if (num > 0) {
int n = 0;
while (num != 0) {
num >>= 8;
n++;
}
return n;
}
}
- 761,203
- 64
- 569
- 643
Python example: no logs or exponents, just bit shift.
Note: 0 counts as 0 bits and only positive ints are valid.
def bits(num):
"""Return the number of bits required to hold a int value."""
if not isinstance(num, int):
raise TypeError("Argument must be of type int.")
if num < 0:
raise ValueError("Argument cannot be less than 0.")
for i in count(start=0):
if num == 0:
return i
num = num >> 1
- 732,580
- 175
- 1,330
- 1,459
- 15
- 4