#include <iostream>
using namespace std;
void setBits(int& number, char ch, int pos){
for(int i = pos, j = 1; i < pos + 8; (ch&(1<<(j-1))) ? number |= 1 << i - 1 : number &= ~(1 << (i-1)), i++, j++);
}
int main(){
int value1 = 16384; // 100000000000000
int value2 = 32767; // 111111111111111
int value3 = 16511; // 100000001111111
char a = 0xFF; // 11111111
char b = 0xAA; // 10101010
char c = 0x83; // 10000011
setBits(value1, a, 3);
cout << value1 << endl; // 100001111111100, 17404
setBits(value2, b, 1);
cout << value2 << endl; // 111111110101010, 32682
setBits(value3, c, 3);
cout << value3 << endl; // 100001000001111, 16911
return 0;
}
Friday 22 November 2013
Set Bits Function
Another challenge was given by Fardad today. We have to create a function to set the bits of an integer using the bit pattern of a character and a given position. Here it is:
Wednesday 20 November 2013
A Class for Bits
For this week, Fardad had us code a class that would handle a string that represented a bit pattern and overload the casting operator to have it represent them as integers and floats (at least that's what I thought he wanted). There is two approaches that I am aware of. First, after copying the bit pattern, we can calculate them manually using our code, or we can be lazy and transfer the bit pattern into a variable's bit pattern literally and have it casted to whatever we want it to represent. I went with the latter.
Saturday 16 November 2013
Integer and Floating Point Numbers to Binary
For this week, we are to do something for Fardad's class, I don't remember what (something about binary numbers). Anyways, here is my code for converting integers and floating point numbers to its bitwise representation in memory.
Thursday 14 November 2013
Doubly Linked List
Here is my implementation of a doubly linked list. More functions will continue to be added for fun.
https://github.com/wongbsn/Codepad/tree/master/DoublyLinkedList
https://github.com/wongbsn/Codepad/tree/master/DoublyLinkedList
Tuesday 12 November 2013
More on Templates
Today in OOP344 we went over the basics for class templates. For review here is a picture taken in class on the rules of creating a class template:
Fardad's beautiful handwriting
According to Fardad, we will not be learning more advance template concepts such as template specialization and partial specialization. That is unfortunate to hear as templates are conceptually complex and interesting. From what I've learned so far we can create specialized templates which means we can create a special case scenarios for certain types (instead of a previously coded general template) by doing something like this:
template<> // no template parameters, compiler looks ahead (general template must exist)
class Node<bool>{ ... }; // matches previously defined template for class Node
// uses this one if type is bool
We can also partially specialize a template like this:
template <typename A, typename B> // General template
class Node{ ... };
template<typename A> // Partially specialized template
class Node<A, A*>{ ... }; // Explicitly declaring additional parameters
It seems that by providing additional parameters after the class name, we create additional rules for using this template. The compiler will always use the best fit template. For the above example, we still have generic type A, but in order to use this template, we need to pass a type along with a pointer of the same type ie. A<int, int*> a;.
Fardad's beautiful handwriting
According to Fardad, we will not be learning more advance template concepts such as template specialization and partial specialization. That is unfortunate to hear as templates are conceptually complex and interesting. From what I've learned so far we can create specialized templates which means we can create a special case scenarios for certain types (instead of a previously coded general template) by doing something like this:
template<> // no template parameters, compiler looks ahead (general template must exist)
class Node<bool>{ ... }; // matches previously defined template for class Node
// uses this one if type is bool
We can also partially specialize a template like this:
template <typename A, typename B> // General template
class Node{ ... };
template<typename A> // Partially specialized template
class Node<A, A*>{ ... }; // Explicitly declaring additional parameters
It seems that by providing additional parameters after the class name, we create additional rules for using this template. The compiler will always use the best fit template. For the above example, we still have generic type A, but in order to use this template, we need to pass a type along with a pointer of the same type ie. A<int, int*> a;.
Wednesday 6 November 2013
Fun with Data Manipulation
Once again, my friend Adam found a good resource for learning more about C/C++ and computer science. It is a series of YouTube videos of Professor Jerry Cain of Stanford University teaching his CS107 class and it is informative and interesting to watch (almost as entertaining as Fardad's lectures). I really recommend students to watch those videos if they are interested in learning about the concepts that were taught up to now but wanted to know more in depth. In regards to these videos, it taught me how floating point numbers are represented bitwise, which is more complex than integers. The videos did a very nice job explaining this. Also, I really like how Professor Cain manipulates the data to show students how information is read and written in memory. By understanding things at a lower level, it makes the process clearer (at least for me). While teaching about types like structs and arrays, he would show examples of stored data represented in bits and bytes and will do various casts, address incrementation/decrematation, and manipulate their value in such a way that the output can be determined by knowing the size of these types. Here's an example:
int arr[5]; // sizeof(int) = 4, sizeof(short) = 2
arr[3] = 128; // 3 * 4 bytes each [ | | | ][ | | | ][ | | | ][A | | | ][ | | | ] write at 12th byte
// A = binary 10000000 = decimal 128
((short*)arr)[7] = 2; // 7 * 2 bytes each [ | | | ][ | | | ][ | | | ][ A | | B | ][ | | | ] write at 14th byte
// B = binary 00000010 = decimal 2
cout << arr[3] << endl; // It will read this as an integer: 00000000 00000010 00000000 10000000
// Output is 131200
I should also mention that this example was created on the matrix server and the machines are little endian meaning they store the least significant byte in the smallest address first (so the above would normally be read as [ | B | | A ]. Pretty cool stuff.
https://github.com/wongbsn/Codepad/blob/master/Bitwise%20Operation%20and%20Representation/data1.cpp
https://github.com/wongbsn/Codepad/blob/master/Bitwise%20Operation%20and%20Representation/data1.cpp
Tuesday 5 November 2013
About Casting and Data Representation
I've decided to try this blogging business a bit more in hopes that it can help me review and understand concepts a bit better and write down special events that may be worth remembering. Today I believe such an event happened at Seneca. During my OOP344 class, Professor Chris Szalwinski came in to inform us that a course on parallel programming will be available next Fall. Parallel programming is apparently a new and growing thing and the idea of working with multiple cores and with the GPU sounds difficult but exciting. This will be one of the courses I will defiantly consider taking once I get back from my co-op position at RBC. Hopefully, everything will go as planned and I will be able to take that course.
One of the things I enjoy doing at Seneca is learning new concepts with friends and classmates. Today, my friend Adam taught me a bit more about casting. He begins by talking about variables and how they contain a number of information that is important to the compiler such as the identifier, type, address, value, scope, and lifetime. When stored in memory, a variable's type is associated with its identifier, value-set, and value-bit representation. One example he showed us was this:
unsigned int x = 1000;
int y = -1;
if(y > x) std::cout << "y is bigger" << std::endl; // This gets called
What happened was that when comparing a signed with an unsigned, the signed will be implicitly casted as an unsigned, making this -1 into 4.2 billion something. This is understood using modular or clock arithmetic and how numbers are represented in bits. To further explain this, he illustrates the difference between static and reinterpret casting. In a static cast, the value is preserved and the bit pattern is changed whereas in a reinterpret cast, the value is modified and the bit pattern is preserved. What happened is this, -1 is not within the value-set of unsigned integers (0 to 4.2 billion) so the compiler cannot fix the value and modify the bit pattern (static cast) so then it will do a reinterpret cast by looking at the association between the bit patterns and values, and then reads it off as a normal unsigned integer.
Signed Unsigned
<-1, ... ... ... 11111111><4.2B, ... ... ... 11111111>
< 0, ... ... ... 00000000> <0, ... ... ... 00000000>
< 1, ... ... ... 00000001> <1, ... ... ... 00000001>
One of the things I enjoy doing at Seneca is learning new concepts with friends and classmates. Today, my friend Adam taught me a bit more about casting. He begins by talking about variables and how they contain a number of information that is important to the compiler such as the identifier, type, address, value, scope, and lifetime. When stored in memory, a variable's type is associated with its identifier, value-set, and value-bit representation. One example he showed us was this:
unsigned int x = 1000;
int y = -1;
if(y > x) std::cout << "y is bigger" << std::endl; // This gets called
What happened was that when comparing a signed with an unsigned, the signed will be implicitly casted as an unsigned, making this -1 into 4.2 billion something. This is understood using modular or clock arithmetic and how numbers are represented in bits. To further explain this, he illustrates the difference between static and reinterpret casting. In a static cast, the value is preserved and the bit pattern is changed whereas in a reinterpret cast, the value is modified and the bit pattern is preserved. What happened is this, -1 is not within the value-set of unsigned integers (0 to 4.2 billion) so the compiler cannot fix the value and modify the bit pattern (static cast) so then it will do a reinterpret cast by looking at the association between the bit patterns and values, and then reads it off as a normal unsigned integer.
Signed Unsigned
<-1, ... ... ... 11111111><4.2B, ... ... ... 11111111>
< 0, ... ... ... 00000000> <0, ... ... ... 00000000>
< 1, ... ... ... 00000001> <1, ... ... ... 00000001>
Subscribe to:
Posts (Atom)