C++ for a thirteen year old

Pages: 12345
Most of it I understood. Here are my few questions -

>this allows us to think of a number of contiguous bits together forming a value (a number) which is greater than one
So the minimum size for an object representation in memory is one byte?

> if sizeof(int) is 4
So ints can have varying sizes?

>The address of an object of type int is the address of the byte, starting at which the next four contiguous bytes form the object representation of an integer.
So the address only refers to the starting byte, not all the bytes put together?
Also, don't you mean " next three contiguous bytes"? Because the starting byte is counted, three more contiguous bytes give a total of four.

> its object representation takes up
So the meaning of object representation is "the representation of an object in memory"?

> Some subset of bits (typically one bit) in the object representation of a bool make up its value representation.
I didn't understand this sentence.
> So the minimum size for an object representation in memory is one byte?

Yes. A byte is the smallest unit of addressability.


> So the address only refers to the starting byte, not all the bytes put together?

Yes. Each one of those four bytes would have its own distinct address.


> So ints can have varying sizes?

The size of int can be different on different implementations, and on different hardware architectures.
This is C++, we have to deal with real machines.


> Also, don't you mean " next three contiguous bytes"?
> Because the starting byte is counted, three more contiguous bytes give a total of four.

Yes. That is what I meant.


> So the meaning of object representation is "the representation of an object in memory"?

Yes.


> Some subset of bits (typically one bit) in the object representation of a bool make up its value representation.
> I didn't understand this sentence.

The value of a bool is either true or false; to represent this value, one bit is sufficient.
The size of bool is at least one byte; all the bits in the object representation of a bool would not (need not) contribute to determining what its value is.
Alright, I understood. Lets move on to the next topic you have in store for me.
Ok. For the rest of this post, let us assume that on the implementation that we are using:

a. CHAR_BIT == 8 (there are eight bits in a byte)
http://en.cppreference.com/w/cpp/header/climits

b. The encoding for the character 'A' has a value of 65.

c. The type char is an unsigned integral type.
(This is actually not true on the implementation that we are using; let us just assume for argument's sake that it is).

If we have char c = 'A' ;

a. What will be the eight bits (sequence of ones and zeroes) in the object representation of c?

b. If we write int i = c ;, what would be the value of i?

c. Can you write this value as an octal number (integer to the base 8?)
As a hexadecimal number (integer to the base 16?)

Spoiler: http://coliru.stacked-crooked.com/a/bf342e21281ffd07
a) I honestly don't know how to convert decimal to object representation, but I'm going to guess it is the binary representation of 65, which would be 01000001.

b) 65.

c) Octal - 0101
Hexadecimal - 0x41

BTW I haven't seen the spoiler yet.
Last edited on
> I honestly don't know how to convert decimal to object representation.

In general, as programmers, we are concerned about the value representation. In the case of a character type, "all bits in the byte participate in determining the value of the character". For larger types, this need not be true.

Your answers are correct; well done!. Now red this tutorial up to 'Negation in the Binary System' http://www.math.grin.edu/~rebelsky/Courses/152/97F/Readings/student-binary
We'll come to the binary representation of negative numbers a bit later; right now, consider that all the numbers that we are talking about are unsigned.
>Your answers are correct; well done!
Even question a)?
If it is correct, then the maximum value possible for a character would be 11111111 - all 1s. This amounts to 255 in decimal, so the minimum value for an unsigned 8 bit char (byte) would be 0, and the maximum would be 255 right?

Also, I had a look at the paper you linked me to. I didn't have to pay extreme attention to what was given, because I already know how to convert from decimal to binary and binary to decimal. What was new to me was addition, subtraction, multiplication and division. I understood all but division clearly.

As for conversion from decimal to binary, I use method 1. Method 2 is beyond me. Honestly, I think it would be best if I didn't try and redo Method 2, as I have a clear understanding of Method 1.
> so the minimum value for an unsigned 8 bit char (byte) would be 0, and the maximum would be 255 right?

Right. (The minimum value of any unsigned integral type would be zero).

The International Standard for C++ (IS) specifies:
Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2n where n is the number of bits in the value representation of that particular size of integer.

Footnote: This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.


So with the above assumption - 8 bit char (byte) - still in place,
a. what would happen if we assign a value larger than 255 to an unsigned char?
b. what would happen if we try to increment an unsigned char which holds the value 255 by one?
1
2
3
4
5
unsigned char c ;
c = 320 ; // ???

c = 255 ;
++c ; // ??? 
Last edited on
Wait a second. I don't think I interpret the statement correctly:

>the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.

so suppose char c = 500;

would it be

c = c - (c % 256)?

Because the way I understand it is, c is reduced by c modulo 1 + max char value (c = c - (c % 1 + max_char_val). Is this correct?

EDIT: Okay, did some stackoverflow browsing and some experimentation, it turns out my interpretation is wrong.

c = c % 256, not c - (c % 256).

The word "reduced" in the line "the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type" confused me. I think they meant "reduced TO modulo..." while it took it as "reduced BY modulo..."

---------------- Please let me know if my new interpretation is correct, before proceeding to answers

So that being clarified, here are they answers:

a) the compiler would divide the number by 256, and then set it to that value. In the example you gave, c = 320.

So, c = c % 256.

c = 320 % 256
c = 64.

b) When 255 is incremented by 1, it becomes 256.

So,

c = c % 256
c = 256 % 256
c = 0?

I guess the value would be set to 0.
Last edited on
> Please let me know if my new interpretation is correct, before proceeding to answers

Yes. You have got it.


Now, before we move on to Chapter 2, let us look at just one more topic related to bits and bytes.

With the assumption - 8 bit char (byte) - still in place, let us also assume that:
a. sizeof( unsigned short ) is 2 bytes.
b. All the 16 bits in those two bytes are used for the value representation of an unsigned short

1. What would be the largest value that can be held by unsigned short?

2. If we have: unsigned short s = 425; what would the 16 bits be?

3. If we consider the two bytes that make up an unsigned short, could we say that one of those two bytes is the "more significant byte" and the other is the "less significant byte"? Just as if we look at the number 83, we could say that 8 is the "more significant digit" and 3 is the "less significant digit". (Therefore, 83 is greater than 38)
Were my answers correct for the previous one?



1) 510. Reason: two bytes, each byte 255.
2) Not really sure, but my guess is,

11111111 10101010

11111111 makes 255, 10101010 makes 170, total 425.

Now, my question here is, are these two different or do they mean the same?
11111111 10101010
10101010 11111111

3) No you cannot. Reason:

>All the 16 bits in those two bytes are used for the value representation of an unsigned short.

If all of them have a hand in creating the value, you can't call one more significant and one less significant.

Were my answers correct? Also, don't forget to let me know whether my answers for the previous 3 questions were correct or not.
> Were my answers correct for the previous one?

Yes.


> 1) 510. Reason: two bytes, each byte 255.

Can't we think of 1111111111111111 as a single 16-digit binary number?
What would be the value of this number in decimal?
What about this 16-bit number 0000000110101001?

Hint: we do not think of the number 4121 as 4 + 1 + 2 + 1 == 8 or as 41 + 21 == 62.

Now try answering 1, 2 and 3 again.
So bytes can be "attached to each other"?
Yes.
In the same way that in the decimal number 4121, the digits 4, 1, 2 and 1 are "attached to each other".
Alright then.

Answers:

1) Maximum possible value = 1111111111111111 = 65535 (in decimal).
2) 0000000110101001
3) My answer for this remains the same.
> 3) My answer for this remains the same.

We have, for 425 decimal, 0000000110101001 in two bytes.
Byte #zero has: 00000001 and byte #one has: 10101001

The contribution of byte #zero to the value is 0000000100000000 or 256 decimal
The contribution of byte #one to the value is 0000000010101001 or 169 decimal
1
2
3
4
0000000100000000  +                                256 +
0000000010101001                                   169 
================                                   ===
0000000110101001                                   425


The maximum that byte #zero can contribute to the value is 1111111100000000 or 65280 decimal
The maximum that byte #one can contribute to the value is 0000000011111111 or 255 decimal
65280 + 255 == 65535

So, which is the more significant byte? Byte #zero or byte #one?
Byte zero.


Man, I got all three wrong.
So I did a few calculations, and if my answer (Byte zero) is correct, then I can say that I have arrived at a conclusion.

The leftmost byte is ALWAYS the most significant one, provided it has at least a single "on" or "1" value.

Here is proof. Lets take two bytes.

00000001|11111111

The line between them is just for convenience.

Byte #0 - the left byte is at its lowest possible value. It has a single 1. This puts the value of that byte at 256.

Byte #1 - the right byte is at its highest possible value. It is completely made up of 1s. Yet it falls short by 1 - the total is 255.

Lets take another example.

00000001|11111111|11111111

Byte #0 - the left byte is at its lowest possible value. It has a single 1. This puts the value of that byte at 65536.

Byte #1 AS WELL AS byte #2 - the middle and rightmost byte, are at their highest possible values (combined). They are completely made up of 1s. Yet, it falls short by 1. The value is 65535.

So to repeat, my conclusion is (if my answer that Byte zero is more significant in the previous question is correct) that the leftmost byte is ALWAYS the most significant one, provided it has at least a single "on" or "1" value.
> I got all three wrong.

You got the first two right at the second attempt and the third one right after that.


So, here is what we know so far:

a. Integral types have values within a range: a minimum possible value and a maximum possible value

b. Unsigned integral types do not overflow; if we try to give them a value outside the range, they are rounded modulo.

c. If we try to give a value outside its range to a signed integral type, overflow takes place and the result is undefined.
1
2
3
4
5
6
// default int is signed int 
int i = INT_MAX ; // largest value that an int can hold
++i ; // overflow: undefined behaviour
   
i = INT_MIN ;
--i ; // undefined behaviour 


d. Every bit in the object representation may not participate in the value representation (except for char types).
Therefore, every possible bit pattern of the object representation may not have a valid value representation.
1
2
int i ; // uninitialised; the bits in the object representation of i may not hold a valid value representation.
std::cout << i ; // undefined behaviour 


e. When we write a four-byte unsigned integer as hexadecimal 0x01020304, with byte being an octet of 8 bits,
the value of the most significant byte is 0x01 (1)
the value of the least significant byte is 0x04 (4)
the value of the unsigned integer is 1 . 2563 + 2 . 2562 + 3 . 256 + 4

f. There is obviously more to bits and bytes (which we will ignore for the present):
are there restrictions on the memory addresses at which an object may be placed? (alignment)
in memory, would the most significant byte have a higher address than the least significant byte? (endianness)
how are negative values represented in a signed integral type? (twos' complement, ones' complement)
how are floating point values represented?

g. In general, while programming we should think of numbers in a logical manner rather than in terms of bits and bytes. To understand that 345 * 3 yields 1035, which is less than 1500, we do not need any special knowledge about bits and bytes.

h. In general, while programming we should think of characters in a logical manner
In particular, it is a beginners' mistake to assume that 'A' will have a value of 65 everywhere.
It is a beginners' mistake to assume that, char( 'A' + 1 ) would universally yield 'B' because it happens to do so on the implementations one has seen so far.
C++ makes no guarantees about the values of characters other than that the values characters representing decimal digits - '0', '1', ... '9' - will be contiguous and ascending.


Now, move forward to the next topic in the book.
Right.

I'm starting vectors now. After 10-11 pages, bitsets will commence.
Pages: 12345