Data Types¶
1 Lecture 1: Binary And Data Encoding¶
- Representation of integers in binary are fairly straightforward compared to floating point numbers, strings, irrational numbers, etc.
- Base 2 = binary, base 10 = decimal, base 16 = hexadecimal.
- The base of a number is the number of digits in the number system, and then the number is multiplied by the base to the power of the position of the digit. e.g. 123 = 1*10^2 + 2*10^1 + 3*10^0 = 100 + 20 + 3. and 1011 = 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 = 8 + 0 + 2 + 1 = 11. and 0x1A = 1*16^1 + 10*16^0 = 16 + 10 = 26.
Decimal | Binary | Hexadecimal | |
---|---|---|---|
base | 10 | 2 | 16 |
digits | 0-9 | 0-1 | 0-9, A-F |
example | 123 = 1*10^2 + 2*10^1 + 3*10^0 = 100 + 20 + 3 | 1011 = 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 = 8 + 0 + 2 + 1 = 11 | 0x1A = 1*16^1 + 10*16^0 = 16 + 10 = 26. |
- ASCII:
- It is a map for translating numbers and characters to binary and vice versa.
- It is a 8-bit code, so it can represent 2^8 = 256 characters.
- It was good for English, but not for other languages as they need more than 256 characters.
- Unicode:
- There are two flavours of Unicode: UTF-8 and UTF-16 (UTF = Unicode Transformation Format).
- It uses 16 bits, or 32 bits, to represent characters which is enough for most languages.
- An Overflow:
- It happens when you need to carry a bit to the left, but there is no space for it, aka, the number is too big to be represented.
- An overflow gives the wrong result, as the carried bit is lost.
- Example:
2 + 2 = 4
in binary is10 + 10 = 100
, but if we only have 2 bits, then10 + 10 = 00
which is wrong.
- To represent negative integers in binary, we use:
1 complement
: the most significant bit is the sign bit, and the rest of the bits are the magnitude of the number.2 complement
.
- To represent real numbers (floating point numbers), we use:
- The memory word is divided into 3 parts: sign, exponent, and mantissa(fraction).
- For example:
8 bits = 1 bit sign + 3 bits exponent + 4 bits mantissa
that is tha maximum number that we can represent is2^3 -1 = 7
in the exponent, and2^4 -1 = 15
in the fraction, so7.15
is the maximum number that we can represent and7.16
and beyond is an overflow. Fixed point
: a fixed number of digits after the decimal point.Floating point
: a number of digits after the decimal point that is not fixed.
- Big Endian/ Little Endian:
- It is the order of the bytes in the memory.
- Big Endian: the most significant byte is stored in the smallest address (left to right).
- Small Endian: the least significant byte is stored in the smallest address (right to left).
- Example
0123
is stored as0123
in Big Endian, and2310
in Little Endian. - Little Endian stores numbers backwards (fourteen => |4|1|, forty one => |1|4|) 9
- In memory, there is not left and right; you can not say this byte represent (tens) and the bight right to it represent (ones) (assuming every digit is stored in one byte) 9
- To convert a Decimal to a binary:
- Divide the number by 2, and keep the remainder.
- Example:
13 = 1101
as13/2 = 6 remainder 1
,6/2 = 3 remainder 0
,3/2 = 1 remainder 1
,1/2 = 0 remainder 1
. - Example:
123 = 1111011
as123/2 = 61 remainder 1
,61/2 = 30 remainder 1
,30/2 = 15 remainder 0
,15/2 = 7 remainder 1
,7/2 = 3 remainder 1
,3/2 = 1 remainder 1
,1/2 = 0 remainder 1
.
- To convert a Binary to a decimal:
- Multiply each digit by 2 to the power of its position, and add them all together.
- Example:
1101 = 1\*2^3 + 1\*2^2 + 0\*2^1 + 1\*2^0 = 8 + 4 + 0 + 1 = 13
. - Example:
1111011 = 1\*2^6 + 1\*2^5 + 1\*2^4 + 1\*2^3 + 0\*2^2 + 1\*2^1 + 1\*2^0 = 64 + 32 + 16 + 8 + 0 + 2 + 1 = 123
.
- To take the 1 complement of a binary number:
- Flip all the bits.
- Example:
1101 = 0010
. - Example:
1111011 = 0000100
.
- To take the 2 complement of a binary number:
- Take the 1 complement of the number, and add 1 to it.
- Example:
1101 = 0010 + 1 = 0011
. - Example:
1111011 = 0000100 + 1 = 0000101
.
- Examples:
// convert 32 to binary to 8 bits
32 =
32/2 = 16 remainder 0
16/2 = 8 remainder 0
8/2 = 4 remainder 0
4/2 = 2 remainder 0
2/2 = 1 remainder 0
1/2 = 0 remainder 1
= 00100000
// take the 2 complement of 32
100000 = 11011111 + 00000001 = 11100000
// find the 2 complement of `00011100`
00011100 = 11100011 + 00000001 = 11100100
// convert 25 to binary
25 =
25/2=12 reminder 1
12/2=6 reminder 0
6/2=3 reminder 0
3/2=1 reminder 1
1/2=0 reminder 1
= 00011001
// take the 2 complement of 25
11001 = 11100110 + 00000001 = 11100111
// convert 128 to 8 digit binary
128 =
128/2=64 reminder 0
64/2=32 reminder 0
32/2=16 reminder 0
16/2=8 reminder 0
8/2=4 reminder 0
4/2=2 reminder 0
2/2=1 reminder 0
1/2=0 reminder 1
= 10000000
2 Lecture 2: Elementary Data Types¶
- Also known as primitive data types.
- Includes:
integers
(int, byte, short),floating point numbers
(float, double),characters
(char),booleans
…etc.
Type | Size (bits) | size (bytes) | Description | Kind of Data | Range of Values |
---|---|---|---|---|---|
byte | 8 | 1 | 1 byte signed integer | integer | -128 to 127 |
short | 16 | 2 | 2 bytes signed integer | integer | -32,768 to 32,767 |
int | 32 | 4 | 4 bytes signed integer | integer | -2,147,483,648 to 2,147,483,647 |
long | 64 | 8 | 8 bytes signed integer | integer | ⨦ -9,223,372,036,854,775,808 |
float | 32 | 4 | 4 bytes floating point | real | |
double | 64 | 8 | 8 bytes floating point | real | |
char | 16 | 2 | 2 bytes character (unsigned) | character | All unicode values from 0 to 65535 |
bool | 1 | ⅛ | 1 bit boolean | boolean | true or false |
- The 2-byte char type supports UTF-16, but has another flavour which is 4 bytes long and supports UTF-32.
- The type
Enum
is considered a primitive type in some languages, and a derived type in others. We will consider it a Elementary type. - Computers can only understand integers, so all other types are converted to integers (in a binary format) before being processed.
3 Lecture 3: Composite Data Types¶
- It is either Derived or User-defined.
- Derived types are built from elementary types. Example: Array, Pointer, Function.
- User-defined types are built from other user-defined types. Example: Struct, Union, Class.
Type | Description |
---|---|
Array | A collection of elements of the same type. The size must be predefined. Referenced by index. |
String | An Array of chars. |
Struct | Also named Record or Class, which all represent Objects. |
Reference | A pointer to a memory location. The variable is bound to the memory location. |
4 LEcture 4: Representing Real Numbers¶
- Floating point numbers are represented in Scientific Notation or Exponential Notation.
- Irrational numbers are represented as approximations.
- Required things to represent a floating point (example: 123 * 10^(-3)):
- Sign: one bit to represent the sign of the number.
- Magnitude or Mantissa: the number itself (123).
- Sign of the exponent: one bit to represent the sign of the exponent (-).
- Magnitude of the exponent: the exponent itself (3).
- The base of the exponent: the base of the exponent (10).
- Location of the decimal point: the location of the decimal point (3).
5 LEcture 5: Variables Binding and Scope¶
- Names :
- Names are handles to an entity within the program, such as a variable, a function, a class, a module, or a package…etc.
- Names are denoted by identifiers.
- Identifies usually allow letters, digits, and underscores.
- Lifetime: the period of time during which the entity exists in memory.
- Scope: the portion of the program where the name binding is valid.
- L-value: the left side of an assignment statement. Usually an address in memory.
- R-value: the right side of an assignment statement, usually the exact value of the variable.
- Binding:
- Binding is the association of a name with an entity, it means the name is becoming known to the compiler; and the entity is being created/allocated/instantiated/assigned…etc.
- Binding can happen during:
- Compile or Translation Time: Before the program is executed.
- Load Time: During the loading of the program into memory.
- Run Time: During the execution of the program.
- Static Binding: The binding is permanent during the lifetime of the program. Example: A global variable. Lifetime: the program. Scope: the program.
- Dynamic Binding: The binding is temporary during part of the lifetime of the program. Example: A local variable. Lifetime: the function call (part of the program lifetime). Scope: the function.
- Variables:
- A variable in imperative languages is **six-tuple**of:
<name, address(location), value, type, lifetime, scope>
. - Each property in the tuple is bound (assigned a value) at a different time.
- The
name
is bound at compile time. - The
address
(l-value) is bound at load time/runtime, or runtime only depending on the language. - The
type
is bound at compile time or runtime depending on the language. - The
value
(r-value) is bound at load time (for global constants) or runtime. - The
lifetime
is bound at compile time. - The
scope
is bound at compile time.
- A variable in imperative languages is **six-tuple**of:
- Dynamic Variables:
- The allocation of memory for dynamic variables is done at runtime (after the program has started).
- Two types of Dynamic allocations:
- Explicit: The programmer must explicitly allocate and deallocate memory for the variable. Example: C++
new
anddelete
operators, Cmalloc()
andfree()
functions. - Implicit: The language automatically allocates (when the execution is within the scope of the variable) and deallocates (when variable leaves the executions scope) memory for the variable. Example: Java, Python, C#.
- Explicit: The programmer must explicitly allocate and deallocate memory for the variable. Example: C++
10 Binding¶
- Binding Time: The time at which the binding is done, which is:
- Dynamic Binding: at execution time using assignment statements or parameter passing.
- Static Binding: at:
- Translation time: during compilation or interpretation or loading. e.g. Global variables (at load time).
- Language Implementation: during the implementation of the language. e.g. bind values to representation, bind operations to machine code.
- Language Definition: during the definition of the language. e.g. Language structures, built-in types and notation for values.
- Binding Examples:
- Bind
+
to the addition operation: happens at language definition, implementation. - Bind
1+3
: happens at translation time, as both 1 and 3 are constants. - Bind
x+1
: happens at runtime, as x is a variable, and its value is not known until runtime.
- Bind
- Binding Keyword vs binding Reserved word:
- Both happen at language definition.
- Reserved words are keywords that cannot be used as identifiers.
- Reserved words can not be redefined, while keywords can be redefined.
- More Early binding means more Efficient code, but less Flexibility (Late binding means more Flexibility but less Efficient code).
- Early binding is done at compile time or load time. While late binding is done at runtime.
- Recursion is an example of late binding, as the function is called within itself, and the function is not known until runtime.
Binding Storage¶
- Bindings are stored at compile time or during execution.
- At compilation: Declarations are stored in symbol tables that maps names to attributes.
- At Execution:
- Runtime: maps names to memory addresses.
- Contents: maps memory addresses to values.
Variables¶
- Dereferencing: obtaining value of variable 10.
- Aliasing:
- Changing the name bound to a variable, using call by reference.
- A new name is bound to the same memory location and value.
- It is different from copying the value of a variable to another variable (call by value) where a new name is bound to a new memory location and value (equals to the original value).
Scope¶
- Static Scoping:
- Determines the scope of the variable at compile time by analyzing the program structure (lexical structure, aka. source code blockings).
- Symbol tables are used to store the scope of variables as they are Stacks when entering a new scope, push new declarations. As soon as program is exiting a scope, pop old declarations.
- Dynamic Scoping:
- Symbol tables are built at runtime, push/pop declarations as the program is executing.
- Usually associated with dynamic typing.
- LISP, APL are examples of languages that use dynamic scoping.
Lifetime¶
- Static lifetime allocation:
- The memory is allocated at compile time.
- When a function returns, the memory is not deallocated, that is the values from previous function calls are still in memory.
- Example: Fortran.
- dynamic lifetime allocation:
- When a function returns, the memory is deallocated, all local variables are removed from memory, and when the same function get called again it will allocate new memory for the local variables (fresh).
- Example: C.
- use Activation Records to store the local variables of a function call.
- Activation Records:
- It stores the local variables and parameters of a function call.
- It is stored in the Stack and is pushed when a function is called and popped when the function returns.
- A procedure may have more than one activation record in the stack, if it is called recursively.
6 Elementary Data Types¶
Integer¶
- The 2’s complement is used to represent negative integers.
- To get the negative representation of a number, we flip all the bits (get the 1’s complement) and add 1.
- Example:
1
in binary is00000001
, the 1’s complement is11111110
, and the 2’s complement is11111111
. So-1
in binary is11111111
.127
in binary is01111111
, the 1’s complement is10000000
, and the 2’s complement is10000001
. So-127
in binary is10000001
.
- A negative value is always represented by the leftmost bit being
1
. - While the 1’s complement is used to represent negative integers; the 2’s complement is the most used to represent negative integers.
- Division of two integers returns only the quotient, while modulo returns only the remainder such that
a/b
can be represented asa = q*b + r
whereq
is the quotient andr
is the remainder ora = b*(a/b) + (a%b)
.
Enumeration (Enum)¶
- In C:
typedef enum {Off, Low, Medium, High} Heat;
, but you can still use any integer value for the enumeration.Heat h = 5;
is valid, although it is not one of the enumeration values. - In Ada:
type Heat is (Off, Low, Medium, High);
, and you can’t use any integer value for the enumeration.Heat h = 5;
is invalid and will cause a compilation error. - C++ throws a warning if you use an integer value that is not one of the enumeration values, but you can still work around it by casting the integer to the enumeration type.
- In Effel, the enums are not supported, as they kept the language simple and easy to use, you can achieve the same functionality using your own logic and assertions.
Character¶
- In Ada:
Character
is an enumeration of all the characters in the ASCII table (256 characters).- To use the 16-bit Unicode character set, you need to use the
Wide_Character
type.
- In C:
Character
is an integer type that can hold values from0
to255
.- Which means that
'A' + 10
is a valid expression, and it will return the value of'A'
in the ASCII table plus10
which is65 + 10 = 75
(10 letters afterA
) that is'K'
. - To use the 16-bit Unicode character set, you need to use the
wchar_t
type.
Boolean¶
- In Ada:
Boolean
is an enumeration ofTrue
andFalse
.True
is represented by1
andFalse
is represented by0
.
- In C:
Boolean
is an integer type that can hold values from0
to255
.0
isFalse
and any other value isTrue
.bool b; b = b + 1;
is valid, andb
will beTrue
after the assignment (source of bugs).
Subtype¶
- A Subtype is a subset of the values of a type, and it is used to restrict the values of a type to a specific range (of integers for example).
- Example:
Temperature
is a subtype ofInteger
that is restricted to the range of0
to100
, although it is valid (from computer perspective) to set101
for temperature, it does not make sense. - The Type of the subtype is determined at compile time, while if the value lies within the range of the subtype is determined at runtime.
- The subtype is NOT a distinct type, but it has the same type as the parent type with a restricted range of values.
Derived Types¶
- A Derived Type can be derived from a parent type and inherits all the properties of the parent type; but both types are two distinct types. You can still convert between the two types, but you need to do it explicitly.
- Example: in ADA:
type Altitude is Integer range 0..1000;
,Altitude
is a derived type fromInteger
and it is restricted to the range of0
to1000
.- Altitude is a distinct type from Integer, and you can’t assign an
Altitude
value to anInteger
variable without explicitly converting it usingAltitude(10)
for example.
- Both Subtypes and Derived Types are used to restrict the values of a type to a specific range, but Derived Types are preferable as they are safer and portable, and their drawback is that they need manual conversion between the parent type and the derived type. But the Subtypes are not portable and they are not distinct types, but they are easier to use as they don’t need manual conversion.
Expressions¶
- Expressions can be
literal
orvariable
, orcomplex
. - Literal expressions are the values themselves, like
5
or'A'
. - Variable expressions are expressions that contain variables need to be evaluated, like
a + b
. - Complex expressions involve operators, system or user-defined functions, and/or combinations of the above, like
a + b * sin(c)
. - Expressions are evaluated to produce a value.
- The value of a variable is the content of the memory cell denoted by the variable.
- Passing parameters to expressions:
- Prefix notation is used to denote function calls, like
sin(x)
, x is passed as a parameter to thesin
function. - Infix notation is used to denote operators, like
a + b
, a and b are passed as parameters to the+
operator.
- Prefix notation is used to denote function calls, like
- The precedence of operators is determined by the language, and it can be overridden using parentheses.
- The associativity of operators is determined by the language, and it can be overridden using parentheses.
- Precedence and associativity are used to determine the order of evaluation of expressions, and should never left to the compiler to decide; it should be explicitly defined by the programmer.
- Constant Folding is the process of evaluating constant expressions at compile time, and it is used to improve the performance of the program. Example:
5 + 3
is evaluated at compile time to8
, and the compiler will replace5 + 3
with8
in the code and no evaluation will be done at runtime. - Reverse Polish Notation (RPN) is a notation that does not use parentheses, and it is used to evaluate expressions without the need for parentheses. Example:
a + b * sin(c)
is written asa b c sin * +
in RPN. ora * (b + c)
is written asa b c + *
in RPN.
Assignment Statements¶
- Assignment statements are used to assign values to variables as
variable = expression;
. - l-value is the left side of the assignment statement; it must be a memory location (variable), or an expression that evaluates to a memory location.
- r-value is the right side of the assignment statement; it must be an expression that evaluates to a value, which is then stored at the memory location denoted by the l-value.
- multiple assignments denoted by
a = b = c = 5
, and it is evaluated from right to left.c
is assigned 5, b is assigned the value ofc
which is 5, anda
is assigned the value ofb
which is 5. It can be interpreted differently in different languages, so it is better to avoid it. - In c, assignments are expressions, while in Ada they are statements.
- Static values are values that are known at compile time, like
5
or'A'
. - Constant values are values that cant not reassigned; they can be defined at runtime, but they can’t be changed after that during their lifetime.
- For each assignment, an instruction must be executed to copy the value from the r-value to the l-value. If the value spans more than one memory word, then multiple instructions must be executed to copy the value from the r-value to the l-value.
7 Composite Data Types¶
Records¶
- Also known as Structures in C.
- Records have members in C, fields in Pascal, and components in Ada.
- Each member has a name and a type that can be any type, including another record.
typedef enum {Black, Blue, Green, Red, White} Colors;
typedef struct {
char model[20];
Colors color;
int speed;
int fuel;
} Car Data;
- The entire record is stored in a contiguous memory area (usually), thus accessing members is very efficient as they are stored in adjacent memory locations according to their order in the record and their size.
- If a record contains 4 members, each of size 4 bytes, then the record will be stored in a contiguous memory area of 16 bytes, the first member will be stored at address
x
, the second at addressx + 4
, the third at addressx + 8
, and the fourth at addressx + 12
. - If the member is a pointer, then the pointer is stored in the record, but the object it points to is stored in a different memory location, that needs to be allocated and deallocated separately.
Arrays¶
- Array is a record where the members are of the same type, and they are accessed using an index.
- The index can be an integer, or a character, or any other type that can be converted to an integer.
- The most important function of an array is to map a logical index to a physical address, that is to map an index to a memory location (variable value).
- Trying to modify
array[index]
, will result in error ifindex
is out of bounds, nad it may modify a different variable ifindex
is out of bounds (the variable that is stored in the memory location after the array). - Array type checking is a powerful tool for improving the reliability of programs; however, the definition of the array bounds should not be part of the static definition of a type.
- Array Subtypes is an index constraint applied on unconstrained array type. Example:
Day[] Month
is an array of 31 elements, each of typeDay
.
Strings¶
- Strings are an array of characters.
- In c, Strings are terminated by a null character
\0
, and they are stored in a contiguous memory area. When copying a string, the null character must be copied as well, otherwise the string will not be terminated and the content of the memory location after the string will be considered part of the string which corrupts the data. - First, strings where stored in a contiguous memory area, and the length of the string needed to be computed every time. Then, the length of the string was stored in a separate memory location, and the string was stored in a contiguous memory area, but this made the string modification more complex as the length of the string needed to be updated every time the string was modified.
Multidimensional Arrays¶
- Multidimensional arrays are arrays of arrays.
- Ada has special notation for multidimensional arrays, but it can work fine with the array of arrays notation.
-
Indexing of an array:
- To find the the memory location of element
i
within an arrayA
, we need to know the size of each elements
, and the starting address of the arrayA
asAddressOf(A[i]) = AddressOf(A) + size(element) * (i - A[First])
. - If
A[First]
is 0, thenAddressOf(A[i]) = AddressOf(A) + size(element) * i
which optimizes the computation; this why arrays in c start at 0. - You can use pointers to access arrays, which is more efficient but more difficult to understand.
typedef struct { // . . . int field; } Element; int count = 100; // number of elements in the array Element a[count]; // initialize the array Element* ptr; // pointer to the first element of the array // loop through the array for (ptr=&a; ptr < &a + count * sizeof(Element); ptr += sizeof(Element)>){ // you can access the element using *ptr }
- To find the the memory location of element
-
Indexing of Multidimensional arrays:
- My be inefficient.
- Arrays are stored in a contiguous memory area, so the index of the first element of the array is enough to compute the index of any element in the array.
11 Decimals¶
- Decimals are used to store numbers with a fixed number of digits after the decimal point.
- Usually used with money, they don’t have floating point as numbers are stored as integers.
- Decimals use more memory and have limited range, but they are more accurate, no rounding errors, no exponent, and no overflow.
- Example: Binary Coded Decimal (BCD), each digit is stored in 4 bits, so the range is 0-9, and the number 1234 is stored as
0001 0010 0011 0100
.
8 Dynamic, Static, Strong, and Weak Typing¶
- Dynamic vs Static:
- Static typing requires the programmer to define the type of variable before creating it;
- while dynamic typing can infer the type of the variable from the value assigned to it.
- Strong vs Weak:
- How flexible the language is in allowing operations on different types of variables, and how it handles type errors.
- E.g. adding a string to an integer or float to an integer.
- Strongly typed throws on operations on different types, while weakly typed coerces the types to match.
- Weakly typed languages allow for reassigning a variable to a different type, while strongly typed languages don’t.
- E.g. in Python,
x = 1
andx = "hello"
are both valid, but in Strongly typed language,x = 1
is valid, butx = "hello"
is not.
- Static typed languages: C, C++, Java, C#, Ada, Pascal, Fortran, Cobol, and Algol.
- Dynamic typed languages: Python, Ruby, Perl, Lisp, Scheme, Smalltalk, and JavaScript.
- Strongly typed languages: C#, Java, Go, Python, C++, …etc.
- Weakly typed languages: JavaScript, PHP, …etc.
- Python is a dynamic, strongly typed language.
- Degrees of strength or weakness vary from one language to another. C > C++ > JS.
References¶
-
UoPeople. (2023). CS4402: Comparative Programming Languages. Lecture Notes Unit 3. Lecture 1: Binary And Data Encoding. ↩
-
UoPeople. (2023). CS4402: Comparative Programming Languages. Lecture Notes Unit 3. Lecture 2: Elementary Data Types. ↩
-
UoPeople. (2023). CS4402: Comparative Programming Languages. Lecture Notes Unit 3. Lecture 3: Composite Data Types. ↩
-
UoPeople. (2023). CS4402: Comparative Programming Languages. Lecture Notes Unit 3. Lecture 4: Representing Real Numbers. ↩
-
UoPeople. (2023). CS4402: Comparative Programming Languages. Lecture Notes Unit 3. Lecture 5: Variables Binding and Scope. ↩
-
Ben-Ari, M. (2006). Understanding programming languages. Weizman Institute of Science. Chapter 4: Elementary Data Types. ↩
-
Ben-Ari, M. (2006). Understanding programming languages. Weizman Institute of Science. Chapter 5: Composite Data Types. ↩
-
Hurd, T. (2021). Introduction to Data Types: Static, Dynamic, Strong & Weak. SitePoint. https://www.sitepoint.com/typing-versus-dynamic-typing/ ↩
-
Curren M. J. (1994). Little Endian vs. Big Endian. NovelTheory. https://www.noveltheory.com/TechPapers/endian.html ↩↩
-
Lecture 6: Bindings by Benjamin J. Keller of the Department of Computer Science, Virginia Tech available at: http://courses.cs.vt.edu/~cs3304/Spring02/lectures/lect06.pdf ↩↩
-
Lecture notes in Programming Language Theory by Nancy E. Reed of the University of Hawaii available at: https://pdfs.semanticscholar.org/ce14/aff89ec1e53c5df86cfabe607cb33af3a54d.pdf ↩
-
Programming Languages Session 2 – Main Theme Imperative Languages: Names, Scoping, and Bindings by Dr. Jean-Claude Franchitti of New York University available at: http://www.nyu.edu/classes/jcf/g22.2110-001_sp11/slides/session2/ImperativeLanguages-NamesScopingAndBindings.pdf ↩
-
Article that describes 2’s complement from Cornell University Available at: http://www.cs.cornell.edu/~tomf/notes/cps104/twoscomp.html ↩