 So, we have already seen that. So, the some of these slides are repeated because the last lecture was a little rushed. I decided we will do another pass where we will go through things which are clear relatively quickly and then I will dwell a little more on things which are not clear. So, some of this basic stuff should be ok by now. In decimal you write down decimal numbers and then you can increment it. First you increment the unit place if that overflows you carry over to the tens place and so on. Binary is exactly the same. So, suppose we have 8 bit binary numbers those look like values between 0 0 0 0 0 0 0 0 through 8 ones and you clock up from the smallest value of all zeros in steps of 1. The very next value is going to be all zeros followed by a 1 in the rightmost position that is 1 decimal. And then when you try to increment it again the so called binary unit position overflows here and then you carry over to the tens or 2's position in binary that is equal to 2 decimal. If you increment it again the lowest significant bit or LSB that is increased to 1 that is a 3 then both of these overflow. So, the next number is 4 which is 1 0 0 and so on. So, there is nothing profound about it with a little practice you can read binary numbers fairly easily. So, you keep doing that until you end up in the last number which is 1 1 1 1 1 1 1 1 1 1. If you try to increment that again the overflow bit disappears from the left and you roll back to 0 0 0 0 0 0 0 0 0 0 0. So, 255 is followed by 1 yeah by 0 that is one way to look at it that will give you only non negative numbers 0 and the positive numbers and that is a little bit of a problem because we also want negative numbers and that is implemented through what is called 2's complement arithmetic. Positive numbers you go from the pattern of all zeros as decimal 0 to the pattern of all 1's which is 255 that will be the range of positive numbers. If you want negative numbers the 2's complement representation is that you go to the last positive number which is the last number with 0 in the leading position which happens to be 127 and what used to be plus 128 is now no longer a positive number. So, those things are gone what happens is you come back to the next number which is 1 followed by all zeros that becomes minus 128. So, the wraparound changes and then you start incrementing again until you go to minus 1 which happens to be the pattern of all 1's. So, what used to be a wraparound from the largest positive value of 255 back to 0 has now shifted now the wraparound happens from 127 to minus 1 to 28 and minus 1 to 0 is not really a wraparound it is just the next value. So, that is 2's complement arithmetic. Now before getting into longer word representations let us look at what a character means in standard C and C plus plus a character is really a single byte. So, to a first approximation a character is the same as a byte internally it is exactly the same it is 8 bits. The only difference is how the compiler and the system interprets what to do with it. So, you can easily declare. So, when you say character variable a equals 65 that is a declaration this 65 is an integer which is stored in this v a which has 8 bits, but when you print it out because the type of v a is character that 65 is interpreted as a code for the letter a capital A. So, all the letters uppercase lowercase digits punctuation brackets they have all been assigned unique IDs between 0 and 255. So, you could either write character v a equal to 65 or you could also write character v a equals single quote a they mean exactly the same thing. Now if you write out v a this will print a to screen because the assumption is that you want to print the characters representation. If you rather write out the code then you have to write out something a little different you have to say sorry you have to cast it to an int this is called a cast and this tells the compiler that the user wants to see the integer representation not the printable character representation then 65 will be printed. Now C plus plus will also let you compare characters based on their corresponding integers. So, small a is less than small b it is one less. Meanwhile capital A is less than capital D. So, that ordering is there, but between uppercase and lowercase it is an arbitrary convention whether uppercases are bigger or lower cases are bigger integers you cannot depend on that unless you know the whole sequence of assignments between characters and 8 bit integers. So, that is what a character is and another way of printing these numbers to be unambiguous is the hexadecimal code which we already discussed last time 8 bits is equal to 2 blocks of 4 bits each. A 4 bit block can represent values between 0 and 15 and instead of printing 10 11 through 15 those are turned into single character digits that is called the base 16 system. So, base 10 you go from 0 through 9 base 16 you go from 0 through 15, but 10 through 15 are written as a b c d e f that makes it easy to print these numbers in fixed format lengths. For example, every byte now becomes 2 hex digits. So, 2 3 hex is 2 times 16 plus 3 c 5 hex is c times 16 plus 5 the same as the decimal type system it is only the base or radix has changed. To disambiguate this to the compiler when you are writing the code you have to write hexadecimal numbers prefixed with 0 x. So, the compiler know it is not decimal it is to the base of 16 and we have seen a print of demo showing this. So, we have now covered bytes and characters bytes are the internal representation. In C there is no byte data type in java they made a byte data type to make this distinction clear because in java a character is not necessarily one byte. To support all the international languages the character was made possibly wider we will not go into that. Now, what is the reason that you would like to compare characters what why is it useful that a is less than b. The reason is that when we construct strings like hello world out of characters and I give you a whole list of I give you a whole list of strings starting from Amit Khan to Zanzibar you can now sort them in some dictionary order and then you can search these lists to go to the right word or the right phrase quickly. And that is very very useful in database applications that is why characters have an underlying ordering on them as well. So, that we can then order strings now we also discussed that only one byte with values between 0 and 255 or between minus 128 and 127 may be too short a range. And for most applications you will need integers with larger capacity. And that is why the language provides short and int and long int those are 16, 32 and 4 bits respectively. And those are organized in RAM in multiples of bytes fixed series of bytes. And usually most architectures will insist that if you are storing a 2 bit short then the first sorry 2 byte short the first byte has to be at an even address. If you are putting down a 4 byte integer in RAM many architectures for simplicity of addressing will insist that the first byte starts at an address which is a multiple of 4. There are some small details like that, but it is not too important for our understanding. So all we need to understand is that a fixed length memory buffer of length 4 bytes is reserved to store an integer. And you may read the integers for example, this may be the least significant bit and then you keep wrapping around until you end up at the most significant bit over here. That is the way multi byte integers are stored in RAM, but they are still fixed sizes the size does not change. And that is why the these integers have what is called fixed precision. There is a fixed range of values you can represent if you walk out of that you would have around either way. You take a very negative number try to make it more negative we will should up to a positive number. You take a very positive number you try to increase it further and go back to a negative number. You may have multiple times in one of the labs one exercise was initialize an integer to 40,000 which is larger than the largest sign short which is 32767. And then if you assign it to a short you get a negative number because 40,000 wrapped on 32767 will result in a negative number. But now if you initialize the original integer to 400,000 and then you assign it to the short you will actually logically wrap around multiple times. You still end up with a positive number, but that number is not of course 400,000 which a short cannot represent. Real numbers are represented very similar to decimal very similar to how you would write scientific numbers in decimal scientific notation. It is a mantissa times 10 to the power an integer exponent. So, the both the mantissa and the exponent are turned into binary code. The exponent is either a positive or a negative integer. So, that is represented as 2's complement using 8 bits in case of float and 11 bits in case of double. And the mantissa is a positive fraction and we saw that just like there could be a decimal fraction 0.123. You can have a binary fraction 0.1001. And the value of a position goes like half 1 4 1 8 1 16th. So, the more bits you have the finer grained number you can represent. So, in a float the mantissa occupies 23 bits and in a double the mantissa occupies 52 bits. And then the overall number is either positive or negative. So, for that we reserve one sign bit. So, if you do the calculations you will see that floats can go between this range of maximum and minimum magnitude apart from the sign and double can go between a much larger range. So, you can represent many more numbers using double, but definitely not all real numbers. So, in one of the labs as well as in class I mentioned that you need care because all real numbers cannot be represented. In particular if your code depends on two real numbers being equal some of you already seen it in the labs you cannot really depend on them as being exactly equal. When you declare two floating point variables say F A and F B and you ask is F A exactly equal to F B that is really bit for bit equality. Depending on numeric imprecision you may well end up doing mathematically equivalent calculations on them and yet end up with a few different bits because of finite precision. So, in most cases if you want reliable code and you are comparing floating point numbers you have to compare them within some epsilon window of each other. Otherwise your code might misbehave in unexpected ways. Other issues about finite precision in floating point numbers is in this special values of infinity minus infinity and nan. So, typically overflowing to infinity is handled fairly well by all the programming systems, but if you have a very large number and you are adding or subtracting a very small number you can lose precision. The small number may have no effect because that difference fell of the edge of the mantisabits. So, if you have a calculation where you are adding a huge number of small numbers and the sum is however non negligible you need to do the addition in the correct order. So, that your result is as close as possible to the correct value. So, now I wanted to be a little more methodical about what all you can do with numeric types what kind of operations are allowed on them. So, all the integers support plus binary minus also unity minus you can get 5 and say minus 5. Multiplication which is a star slash which is division and percent which is remainder. So, I divide 7 by 3 you know I get some remainder. Even the characters support plus and minus. So, because characters are fundamentally integers byte integers inside you can also do basic arithmetic operation on them. It may not make sense to multiply characters in that sense, but in any system quote a plus 1 is quote b, but what is quote z plus 1. So, let us try this and now I will print by the way to avoid confusion about what is being printed perhaps we can write things like you know ca equals followed by the actual value of ca. The first is a string it says ca equal to that is exactly what will be printed the second is the actual value of ca and then we will say what is c b. So, the next character after capital Z is the open box bracket in the assignment of characters to codes and there are tables available on the web we can easily find this out. So, that is that we can compare characters you can increment characters, but you do not know where exactly you land. The lower case and the upper case characters are assigned contiguous sequences to make comparison easy. So, you can always they are contiguous, but a is not 1 or anything like that. Meanwhile, the other thing to observe is that 0 through 9 and not 0 through 9 obviously. So, the character 0 is very different from the integer 0. So, this will not work because it is printing the character itself. So, I said that to print the corresponding code you have to cast it to an integer. So, we will talk about cast in more detail later, but the code for 0 is 48 decimal all right. So, what else can we do with numeric types float and double support the usual plus minus multiply divide as well and more complicated operations on floating point numbers like log or exponential or sign cosine etcetera are implemented as functions in a library there are no native symbols for that you call a function you get a return. We will discuss functions in the next week or the week after that. You can also compare numbers using what are called comparison or relational operators. So, you can check if a is less than b, a is less than equal to b, a is equal to b and this equal to is a comparison. So, we need a different symbol as compared to assignment. Assignment uses the single equal sign, comparison uses two equals and it is relatively easy to get it wrong while you are typing. So, be careful about that especially we are using the comparison operator single equal you type two equals you might miss. So, when you are comparing things be careful to type it or greater than equal to or not equal to. So, those are the basic comparison operators and the result of a comparison between two numbers is a Boolean value. A Boolean value is either 0 or 1 we will discuss it right next, but inside c and c plus plus there is no distinct Boolean type. So, those systems use integers to overload the use of Booleans and there are some associated glitches with that. So, the convention is not that 0 is false and 1 is true, the convention is 0 is false and anything else is true. And that is a kind of a mess apart from collapsing the two types because you can write strange expressions like if 5 then do something and 5 is true and so is minus 1. So, you compute Boolean values by expressions like this you say 5 greater than 7 and you bracket it to make sure that 5 is not printed by accident. And 5 greater than 7 is a Boolean expression with value false or 0. So, if you write this c out will print 0, whereas 4 is indeed not equal to 3 and so that the value of that expression will be 1. So, in this case c out will print 1. So, this we have seen some of you have seen it in the labs. So, for those of you are not familiar with Boolean algebra here a very quick refresher is that there are two values in Boolean algebra true and false 0 and 1. And you can combine values there are rules functions for combining the and function is what you would expect both the inputs have to be true or 1 for the output to be 1. The all function again is what you would expect at least one of the inputs have to be 1 for the output to be 1. An important thing to remember in this is that c and c plus plus will do what is called short circuit evaluation. So, if you say that you know evaluate the expression a and b and a is found to be false there is no further any need to evaluate b because the answer is already known to be false. So, for efficiency the compiler will not even you know arrange to evaluate b. Similarly, if you say if a or b and a is found to be true then the expression is already true no matter what b is. So, in that case again b will not be evaluated. So, short circuit evaluation is efficient because it avoids the evaluation of expression that are not required to find the value, but it has an unfortunate side effect in that if evaluation of some of the expressions where to change the state of memory and we can do that with function calls. Then you have to be very careful about understanding the nature of the code we will see that when we discuss increments and decrements on integers. So, remember that Boolean expressions are evaluated in the most efficient way possible and not all parts of the expression will even be evaluated to find the output if possible. There is also the unity operation called not and there if the input is 0 the output is 1 if the input is 1 the output is 0. There is also the binary operation called xor. So, what xor is defined as exactly one of the inputs has to be 1. If both of them are 1 then unlike or in xor the answer is 0. xor is useful for many things as we shall know. Now, you can do logical operations. So, there are two classes of operations in C plus plus one is with Boolean conditions the other is with arrays of bits this is a slightly different. So, one Boolean condition is say 5 greater than 7. So, the value of this is false then there is 3 not equal to 4 the value of that is true I can now combine them by logical and which is represented by 2 amperes. So, that will read like 5 greater than 7 and 3 not equal to 4 right. So, this is false this is true the overall value of this is false. In fact, if you write an expression like this the compiler will arrange that this is never evaluated that is and similarly you have the logical OR operator. This time by convention you go from left to right you evaluate the first one you find that to be false, but for OR there is still hope. So, you have to continue with the second expression evaluate that you find this is true the overall value of this is true or 1. Similarly, there is the not operator. So, you can put a condition inside not and that has the semantics of unary not. So, these Boolean conditions or logical operators are used for conditional execution of statements for looping and program control, but there is an independent set of operations on arrays of bits by which I mean if you look at say an integer that is 32 bits each of them is capable of representing a Boolean value 0 or 1. So, C++ also supports bit wise operations between 2 such vectors or even 1 such vector. So, suppose I have 2 bit 2 nibbles for writing simplicity say 0 1 0 1 and 1 0 1 1 I can and them together using a single end a person and this would give me the logical end of those 2 things. So, 1 and 1 is 1 1 and 0 is 0 all the other that is a logical and if I instead or it I am going to get 1 1 1 1 that is the those are some of the bit wise operators. So, I can do a. So, in this case if I take 2 bit arrays and I say and them together what I mean is and every bit position. So, this bit is this and this, this bit is this and that independently. So, you get like a parallel execution for 8 16 32 or 16. So, in this case to distinguish it from the logical condition of and a single ampersand is used a single bar is used for a or b. There is also an xor operator and there is a not operator which is quill. So, as you can see in this example if you start with 1 0 1 1 0 1 1 0 and the following number by ending it you get a 0 in this position you get a 0 in this position you get 0 anywhere that both of them are not once. Meanwhile if you odd them the same 2 numbers you will get a 1 where any of them used to be once xor will have a 1 where they were different if they are the same you get a 0 if they are different you get a 1 and not or till the twiddle that just inverse the bits whatever there was 0 you get a 1 where there was a 1 you get a 0. So, those are the basic bit array manipulations, but you can also do what is called bit shifts. So, what is the shift? So, if I declare integer c to have value 5 if you write down 5 in binary for 32 bits 32 bits is 4 bytes I have put commas just to show the byte boundaries. The last byte has value 5 and all the leading bytes are 0s that is the integer 5 written in binary. Now, I say take c and shift it left by 2 positions it is really unfortunate of the c plus plus language to keep using the same symbols for multiple purposes it is kind of confusing java has avoided it in most part. So, what happens is that I am saying shift c left through 2 positions. So, 2 0s are injected from the left sorry from the right and the leading 2 0s pop off and disappear. So, bits lost from the left or the most significant bit side 0 bits injected from the right or the least significant bit side and the result is say if this is binary that means this has weight 1 2 4 8 16. So, it is 16 plus 4 the answer is 20 and why is it 20 because I shifted it left by 2 positions which implies a multiplication by 4. If you take a decimal number and shift it left by 1 position you are multiplying it by 10 if you take a binary number and shift it left you are multiplying it by 2 if you shift it twice you multiply it by 4. So, this is a cheap way to multiply numbers by powers of 2 much faster in hardware. Of course, you can also do right shifts and right shifts will be c right shift by 2 positions in this case bits will be discarded to the right, but the left rule is a little different. If originally the most significant bit of c was 0 then 0 bits will be injected. If the original integer had 1 in the most significant bit then according to 2's complement convention the original number was negative. This time the bits injected from the left will be 1's and the reason for doing that is to preserve the sign of the number. If you are saying I want to divide minus 52 by 4 you expect a negative number. So, that is why depending on the original most significant bits the same bit is injected from the left and this is another benefit of using 2's complement. We can only check the first bit to decide if the number is negative or positive and then do arithmetic accordingly. So, minus 5 shifted right by 2 positions gives minus 5 by 2 because minus 5 if you write it down in hex is f f f f f f b and you shift it right by 2 positions you will get f f f f f f e. So, let us try to remember that. So, what is minus 5? First of all what is plus 5? Plus 5 is 1 0 1 in the last nibble 0 1 0 1 and then the others were all 0's all the other bits were 0's the last 4 bits were 0 1 0 1. So, that is 1 4 that was 5. So, how do I write it in hex? Remember in hex I always need this table because I cannot never remember. So, 10 is a 11 is b 12 is c f and a is also 1 0 1 0 1 0 1 1 1 0 0 1 1 0 1. So, that is the table of the last 6 values. So, this one is just 5 and then everything else is 0 1 by 2 by 3 by 4 bytes that is 5 decimal written in hex. So, now to find minus 5 what do I have to do? I have to first invert the bits and then add 1 in 2's complement. So, if I invert the bits what happens? The complement of 0 is f. So, I get f f f f and what happens to this? This becomes 1 0 1 0 and then I add 1 to it luckily it does not overflow and I get 1 0 1 1. Remember the rule for 2's complement to take a number and find its negative you invert all the bits and then you add 1 to it and 1 0 1 1 is that b. So, this becomes f b 5 1 switching becomes 1 0 1 0 plus 1 does not overflow. So, that first 0 goes to f the 5 goes to b. So, minus 5 the hex code is all f's followed by a b and now let us write it down again in that form. So, I have you know I will do a hybrid just to shorten the amount of writing I have to do. So, this will be f and then the b part I will write down as 1 0 1 1. Now, if I start shifting this right by 2 positions what happens is that these 2 drop off and 2 bits are injected from the left, but there will be f's anyway because the original left most bit was 1. So, what I will end up with is let me break this open. So, that all the bits are visible again the last 4 bits is going to be 1 1 1 0 because once from f flowed in as it was shifted and then once also flowed in from the left. So, this is the last nibble then rest of it was f and ff and ff and ff and what is 1 1 1 0 that is e. So, my result so minus 5 shifted right by 2 is equal to ff ff ff e which if you look up your tables will turn out to be minus 2. Why is it minus 2? This is equal to minus 2 decimal because the next number is ff which is minus 1 decimal after all f's we do up around to 0. So, the summary is that this form of right shifts with signed bit injection from the left will correctly give you division by powers of 2, where you of course lose the fractions because they are not fractional now. So, there are many applications of bid operations. For example, to test if an integer is odd or even so to test if a number is odd or even all you have to do is to bitwise and it with 1 right. So, this 1 value in binary will look like all 0's followed by 1 and I am ending it with my original number. So, if the original number was odd its last bit was 1 and the result of this and is 1 whereas if the original number was even then its last bit was 0 and this ending will result in a 0. So, is odd which is the Boolean variable really will turn out to be 0. Just if a number is odd or even all you have to do is a bitwise and with 1. So, for example, 4 bits the number 5 decimal is 0 1 0 1 and I take 1 which is just that I and them together I get that and so yes 5 decimal is odd whereas I take something like say 6 decimal which is 0 1 1 0 it is 2 plus 4 and then I take my same what is called a stencil of 1 I and this together what do I get I get all 0's. So, now what do you how to find the remainder when a number is divided by 8. So, you could always say x percent 8 x percent 8 gives the remainder when a number is divided by 8, but an easier way to find it would be to say x and 7. So, why is that. So, let us take the number say I do not know 11 decimal what is 11 decimal? 11 decimal should be 1 0 1 1. So, that is 8 plus 2 10 plus 1 11. Now, 11 when you divide 11 by 8 the remainder is 3 instead I can take 7 decimal which is 0 1 1 1 and I and it together. So, I have 1 1 0 0 and this is 3. So, whenever you are dividing a number by a power of 2 and you want to find the remainder it is much faster and simpler to actually do an and with the divisor minus 1. So, 8 minus 1 7 and these things are very useful when writing system programs because you know why do you think the number of bits in a fixed length integer go between 8, 16, 32 and 64 there are powers of 2. Your file system is organized you know your files are allocated in units of blocks and those are very often powers of 2 almost always. So, file blocks are usually 512 bytes or 4096 bytes and the entire reason is that you cannot be addressing very quickly by doing this bit operations. So, the next example is little more involved suppose you want to count the number of 1 bits in a 32 bit integer how do you do that? Well checking if a number is odd or even amounts to counting the number of 1s in the least significant position and you also know how to shift numbers. So, bit given these 2 we should be able to do it. So, you repeat 32 times you can go from either end really. We can say we can initialize a variable called number of 1s to 0 and then you say num 1s equals num 1s plus x and 8 followed by all 0s in hex. If you write down 8 0 0 etcetera in hex you realize it is nothing but 1 1 bit followed by all 0 bits. So, I am stenciling the original numbers most significant bit with a 1 if that is 1 I am clocking up num 1s and then I shift it. So, keep shifting and ending. So, let us see a example of that. So, suppose I was told to count the number of 1 in the number 1 0 1 1. So, what I do is I take this number I stencil it with 8 unsigned and this gives me a non 0 number. So, this is not equal to 0 therefore, I chalk up 1 then I shift the original number left I have already dealt with this bit now I have figured this bit was 0 over 1. Now, I shift it left I get 0 1 1 0 I again stencil it with the same number and this time I get all 0s. So, I do not do anything then I shift the number again I get 1 1 0 0 I stencil it again yes I get a 1 non 0 then I shift the number again to get that this 1 has now shifted to the left this time I again get a 1. So, I get another 1. So, of the 4 cycles in this execution I get non 0 twice and. So, I count this up and 3 is the number of bits in the original number. Now, so this is of course, tedious to do if I have to write down this code 32 times for integers and 64 times for long that is just painful coding. So, that is why we use loops many of you are familiar with it already we will cover loops very soon. So, if I have to write down on the board you know I will try to lecture slowly and clearly doing that 108 times this painful. So, I will let you write a for loop for that. So, that is how bit operations work. So, let us look at a small demo of bit ships to see some other subtle points all right. So, see it is no fun doing bit operations without being able to show bits for reasons unknown it turns out that standard C plus plus has no way to directly print a number in binary format this is very very weird. So, I wrote a couple of functions to print unsigned characters and integers in binary how they work will see very soon with loops and so on, but let us now focus only on the main method. So, I initialize unsigned character a to 45 well let us go to the that one next. So, I have an integer C sorry and then I read C from the input and then I just print out C both as decimal as well as in binary. So, into binary C just print C out in binary and then I write shift C by two positions and then I print out D in binary and D in decimal. So, very simple piece of code. So, I do that and suppose I enter say six. So, remember I am shifting by two positions. So, I am dividing by four. So, six in binary and the integer this is 32 bits was 110 this 2 plus 4 and when I divided by 4 that is equivalent to shifting it right two positions. So, the 0 and the 1 drop off and only that last one comes here and that is just 1 and so 6 divided by 4 is 1 when you drop fractions. But, if I do this and I enter say minus 6 let us enter something a little more interesting minus 12 say what was happening there I did not get. So, minus 12 divided by 4 is minus 3. So, minus 12 is all ones followed by 0 1 0 you can verify that and as you can see the shift just drops these two 0s and this 1 0 1 pattern is the right and that is minus 3. Let us try couple of more things suppose I enter minus 13 minus 13 divided by 4 has become minus 4 whereas, plus 13 divided by 4 is 3 this is little unintuitive. So, the explanation is that this is not symmetric about 0 we are following bit shifts and 2s complement convention and this is the result. So, you need to be a little careful about that we do not assume that truncating results of divisions goes the same for positive and negative numbers it does not. So, that is how right bit shifts work now let us look at the first part of the code. So, all this code is available in the website you should start with these and pull around and change a few things and see how it works. In this case we are reading an unsigned character this is not an int and then we print a in binary byte to binary because the character is a byte and then we left shift a to positions and we print it and then I will do some you know bit stenciling operations to see what it looks like. So, first 45 is this quantity it is 1 plus 4 that is 5 plus 8 plus 32 this is 45 if I shift it left by 2 positions what I get is 1 in the biggest position and then you know 1 0 1 coming from here and then 0 1 and then 2 0 have been injected from the left. So, observe that in doing so as a sign number a would have changed from positive to negative as an unsigned number it may not. So, let us verify that. So, suppose instead of binary we print this out as a and then as a shifted left to all in binary all in decimal sorry not in what happens in the first case first case a is interpreted as a character and the corresponding code for 45 is the minus sign. So, printing a is the same as printing a minus sign if I wanted to get the code for a I have to cast it if I cast it then I get 45. Now, as an unsigned integer this quantity is 180. So, on shifting I get 180, but if this were signed then the game would change what would happen it would go negative you have to assign it. So, see the other thing is that if you write an expression like this by default it becomes an integer that is another thing the lab explores if you put a literal value what type is it the default is int in many such cases because it you know overflow that. So, now suppose I say card b equals a less than 2 and then I say int b now it is negative because 180 overflowed, but if I say unsigned card b then it is ok then it is 180. Now, the other important thing is this that rule that the bit injected from the left depends on the original sign bit that is true if the number is signed if it is unsigned it will always inject zeros. So, if you declare a sign you know implicitly variables are signed and you have this quantity 1011 and you shift it right by 1 you are going to get this 1 is going to come there and the left bit injected will be a 1 whereas, if you declare the variables as unsigned then the left bit injected will be a 0. So, if you are trying to do arithmetic on numbers use sign if you are just using bit operations for whatever purpose you have use unsigned because you will not run this risk of injecting a 1 from the left if you are just using the byte as an array of bits then declared unsigned. So, that there is no overflow there is no negative stuff there is no 1 bit being injected and so on. So, to do a quick summary we reviewed integer numbers floating point numbers we saw most of the basic operations on them then we looked at integers logical conditions Boolean conditions and also integer types as arrays of bits and how to do bit wise Boolean operations on those bits. One more example was left in the C code any question so far. So, I do not think you have ever been in this classroom for any other lecture how many of you take other lectures here listen to other lectures is this your first semester in this room or second semester. So, I have a problem with my voice my voice does not work well with PS systems. So, and things work out only if you know the place is fairly quiet and so on. So, if you are trying to protest that my voice is unclear you have to do that distinctly and then stop protesting. So, that you know I can make some progress. So, the last thing I wanted to demo is the following. So, I read a number this is also not actually this is not. So, here is the only two lines you can look at character a is 45 and then all I am doing is I am stenciling a with some pattern and then printing it out in this case it is XOR. So, let me just also print out so, this is very simple I have one input value I am printing it out in binary and then I am printing out a XOR with 55 what is 55? 55 X looks like 0 1 0 1 0 1 0 1 0 1. So, it is the alternating bit sequence just as an experiment. So, see what happened here let me actually write down 55 as well. So, what happens the first pattern is 45 the second is 0 X 55 that is alternating 0 and 1. So, this was 1 that was 1 the result was 0 this is 0 this is 0 the result is 0 this is 1 this is 0 the result is 1. So, that is how XORing is done and in this case you shall see that unsigned should not make a difference I hope. So, it is the same number because XORs do not involve shifting and there is no interpretation of sign XORs will go the same way no matter whether you declare them unsigned or signed. Once we have this values of this different types we can declare variables actually you have been seeing them from write the first lecture you can declare a variable called Fahrenheit you can initialize it to some value. If the value does not change you can declare it to be a const you can also declare initializer values of variables based on other variables that have already been initialized. And I spoke about why initializing and declaring variables is good. Now, one thing you need to be careful about is type conversions and the way literal values get fitted into the variables being declared. So, if you say short X equals 20,000 and then you say int Y equal to X that is no problem because 20,000 fits in a short and int is only wider. So, that conversion will be implicit everything will be taken care of, but what happens if you say int X equals 40,000 and then short Y equal to X you already some of you have seen it in the lab what happens. So, it might overflow and wrap around and so on. So, you need to be careful of that others must be made explicit. So, if you say float X equals 5.6 and then you say int Y equal to X the compiler may or may not be happy about that. So, let us try this out. I will be sloppy and reuse my java stub or something or maybe you should go to float a bunch of stuff there from last time, but let us experiment with declarations mostly today. What else is there to be careful about? So, does this make any sense float you know if you put an int X that is fine if you do not seems like the compiler is ok with it some could be errors it does not make sense to take hello world and turn it into floating power number or does it. So, anytime you write something which looks absurd you should try it out you never know what will actually happen. So, I am actually as almost as clueless about C plus plus as some of you might be. So, let us try this out. So, let us say float I cannot do float X again. So, let us try that does it make any sense. So, it is clearly unhappy right. Now, if I do not even coerce it into a float and just write that it will be the same thing. So, basically it is finding all these character sequences and finding them out of place for a float. So, some things will be guarded by the program something as absurd as this will be guarded, but if you are converting between types which are almost compatible strange things may happen that you cannot predict. So, as we saw rounding it is not rounding or taking a float it is just taking the integer part of numbers. If you say float X equals 7 over 3 versus float X equals 7 over 3 dot let us see what happens right. So, it is looks very very similar one dot is different. So, in one case what happened is that 7 was interpreted as an integer 3 is an integer. Therefore, the result of slash was taken to be an integer which was the integer part of 7 over 3 that was assigned to A. In the second case because 3 dot looked like a floating point number that was turned into either float or double I have to look up which because the slash had one party which is higher precision than the other the value of the whole expression was lifted to the higher precision number and the whole fractional number was assigned into B. So, be very careful about the initialization issues because you might get things wrong because of just one dot. So, that is a result of implicit typing the system sees a literal string in your code and has to understand what type you mean and it picks the least compatible type. So, 3 dot can not fit an integer whereas 3 fits in an integer. Now, by least I do not necessarily mean least precision because otherwise for 3 it might pick byte whether that does not happen. So, after characters and other types. So, last type we will discuss today is string and you know computers do a lot of fun things with strings the whole internet is around strings web pages have lots of strings when you are browsing the web you are clicking on a link that link is a long string which is interpreted to mean a server name and the protocol and the path the path is a string your file name is a string. So, strings are everywhere. So, when we said see out less than less than hello world. Hello world was stored as an array of characters inside RAM. So, to give you a pictorial description remember RAM looks like this one dimensional array of bytes at some point the string started this was H the next was E then there was L another L and so on until there was hello world D and then to mark to the system that the string is over the last character was 00 hex. So, in old C and C plus plus that was the convention that strings will be terminated in the null character. Now this of course is painful because who knows that someday you would like to store a null character in your string itself. See you you declared that a string is an array of character all characters should be kosher in all characters are legal and allowed. Why are we special casing one character and calling it the end of string marker because some day the user may want to store the string in the interior of a string. So, as a general thumb rule in programming and software using what is called in band delimiter is generally a very bad idea because someday a user will try to use that delimiter in the code in the string itself and your code will break. So, a more modern and better way to store strings is the string data type and you declared that by saying string message hello world or you can even do string message equal to hello world because old C and C plus plus had character arrays as legacy the system was set up that the new string class and the old character array class can interact relatively smoothly. So, you can take our old quoted hello world and assign it to a string and you can also get a string back from the new string class character class. So, what can you do with strings? So, string is actually internally implemented as an object and we will see how to do object-related programming in C plus plus as the semester progresses probably around midterm, but here are the basic operations you do not need to understand object-related programming to understand what is going on here. So, let us say you declared message as a data element or variable of type string, the string message. You can now say message.size and that gives you the number of characters in the string. String does not keep any trailing null or anything like that. It independently keeps track of the number of characters in the string in a separate field and that is much safer. You can also pull out the specific character at any specific position in the string. So, you say message.at5 or like an array notation message box 5, you get the character at position 5 in the string starting at 0. In anything that looks like an array in C and C plus plus, the first index is 0. It starts with 0 not 1. So, you get the 6th character in the message or the character at index 5. You can also get a substring of the given string by saying message.subster1,3. What is that? Start at position 1 in the string and go for 3 more characters. Now, if that if walking forward 3 characters takes you past the original string, what will happen? You have to consult the manual. Some of these operations will throw an exception or runtime error or crash. Other operations will silently chunk it. So, if your string is not long enough and you walk past it, the substring will end at the original string and others may return garbage. So, again C plus plus is a little unfriendly with regard to this. The Java string class is friendlier in the sense that you do anything that is fishy it will throw an exception. So, C plus plus may happily do things that you may not know about it for a while. So, all this is implemented by calling methods on the string object and how that is done will see somewhat later in the course. But you do not need to understand that to be able to use it. More string operations, you can search for characters in the string. You can say find the first occurrence of O in Hello World. If the character is not found, it returns some illegal value like minus 1 which does not make sense. Or you can find the last occurrence of a character like find the last of E. You can also compare two strings in dictionary or lexicographic order. So, you can and that is done by taking two messages and saying message 1 dot compared message 2. And this returns an integer which is which can be negative, 0 or positive. If it is 0, it means that the strings message 1 and message 2 are exactly equal. Hello World and Hello World. If message 1 should appear before message 2 in a dictionary or telephone directory, then negative numbers are returned. Whereas, if message 1 should appear after message 2, then a positive number is returned. So, those are the conventions. Let us pull around a little bit with the string class to see how that works. So, the very first program is extremely simple. We are just saying string message hello new line and you are printing out the message. So, this is just and apart from IO stream, you now have to include the library called string. So, that strings are found. Now, let us print out the size. The size is 6. Why is that? It is hello followed by that new line character. The new line character cost you 1 byte in unique systems. In Windows system is cost you 2 bytes. So, just to make life more fancy. So, then we can also initialize, we can reinitialize message to another string. So, the string class and character arrays are interoperable. And then you can print that out and its size and everything changes as you shall see. Move into go with a new line will be 12 characters board. Now, I will informally introduce a for loop and you will see for loop soon enough. So, here I am saying for this variable m x which is initialized to 0 and m x has to be less than the messages size and this is called an auto increment operator. And then I can write down the character at m x, but I also add the integer code. So, at the character value as well as the integer value, let us see what that gives us. So, mood indigo has 12 characters in it. The first is m with byte code 77 followed by o byte code 111 and so on space has a byte code of 32. All this finishes and finally, there is a new line, new line trying to print it goes to the next line and the code of new line is 10. So, that is mood indigo printed character by character. I can append things to other strings. So, I can take mood indigo new line and append take first new line to it and the result is mood indigo take first one after the other. So, appending is as you would expect. And finally, I will show how to take a substring 1 to 3. So, when I say take a substring starting at character position 1 and go for 3 characters because it starts with mood indigo, I will go to o. So, this will be o and then o, o, d. So, you find o, o, d here coming from mood indigo like this. Now, if I took something like say 5 and then take 10 characters, how will that change? So, if I start at 5 and I go for 10 characters it starts with indigo. So, this is 0, 1, 2, 3, 4, 5 and then in going for 10 characters actually includes that new line between the two lines. So, and then goes up to c. So, that is the string class. So, next we will look at expressions and assignments that will be next lecture.