# Discussion 1/17

## Primitive Types

By now we should know about two primitive types:

• int: stores an integer (whole number). It uses 4 bytes of memory, and can take any value between -2*10^9 and +2*10^9.
• double: stores a decimal. It uses 8 bytes of memory, and it can get up to 15 digits of precision. The maximum value for a double is around 10^308, and the minimum is around -10^308.

Here are a few other types we'll see this quarter:

• unsigned: This is similar to int, except it will only store non-negative numbers. The smallest possible unsigned is 0, and the largest possible is approximately 4*10^9.
• long: This is also similar to int, except it uses 8 bytes of memory (instead of 4), and can take values between -8*10^18 and 8*10^18.
• float: Like double, this stores a decimal. It uses only 4 bytes of memory though, so it stores smaller numbers. With float you get about 7 digits of precision, and the values can range between -10^38 and 10^38.
• char: This stores letters, numbers, and special characters. Some example are ~, !, [.
• (A char is secretly represented by a number between -128 and 127. Google 'Ascii Table' to find out which numbers correspond to which chars.
• bool: This stores either 1 or 0. Variables of type bool are used when dealing with true/false problems. 1 is supposed to represent true, 0 is supposed to represent false.

#### Maximum size of type int

As we said above, the maximum size of an integer is roughly 2*10^9. Below is a piece of code that shows what happens when we try to make an integer bigger than the maximum.

```#include<iostream>
using namespace std;

int main() {
int x = 2e9;  // Start x at 2000000000
cout << "x is " << x << "\n";

cout << "Increasing x by 10^8" << "\n";
x = x + 1e8;  // Make x bigger
cout << "x is now " << x << "\n";

cout << "Increasing x by 10^8" << "\n";
x = x + 1e8;  // Make x bigger
cout << "x is now " << x << "\n";

cout << "Increasing x by 10^8" << "\n";
x = x + 1e8;  // Make x bigger
cout << "x is now " << x << "\n";
cout << "What happened here?" << "\n";

return 0;
}
```

#### Decimal precision: float and double

Here's are some programs that are supposed to show the amount of precision we can get out of the float and double types

```// Maximum precision of float and double
#include <iostream>     // Library for cout, fixed
#include <iomanip>      // Library for setprecision
using namespace std;

int main() {
cout << fixed << setprecision(5);
/* This tells c++ to always output 5 decimal digits
for every decimal. It doesn't actually
output anything to the console. */

float f = 3.1415926535897932384626433;
cout << f << "\n";
return 0;
}

/*
Stuff to do:
(1) Put in many different numbers for setprecision
(2) Replace float with double and repeat
*/
```

#### Size of float

```// This program shows the maximum value of a float variable
#include <iostream>     // Library for cout, fixed
#include <iomanip>      // Library for setprecision
using namespace std;

/*
Don't worry about the content of this program. It contains a lot of stuff
that we haven't covered yet. Here is what it does: It calculates all the
powers of 10 between 10^0 and 10^40 and outputs them to the console.

The key thing here is that we are storing these numbers in a float variable.
We're going to see what float can do.
*/
int main() {
const unsigned int POWER = 40;
cout << setprecision(7);
float f = 1.0;
for (int i = 0; i <= POWER; i++) {
cout << "10^" << i << " = " << f << endl;
f *= 10;
}
return 0;
}

/*
Stuff to do:
(1) Mess with setprecision.
(2) Try different numbers of f
(So we will be calculating f*(10^40) instead of just 10^40)
*/
```

#### Size of double

```// This program shows the maximum value of a double variable
#include <iostream>     // Library for cout, fixed
#include <iomanip>      // Library for setprecision
using namespace std;

/*
This program is almost the same as the above one. We're just going to replace
float with double. Since double can handle a lot more numbers than float, we
need to go to a much higher power of 10. This program will only output some
of the data (just so we don't clog the console with numbers).
*/
int main() {
const unsigned int POWER = 340;
cout << setprecision(14);
double f = 1.0;
for (int i = 0; i <= POWER; i++) {
if(i%20==0)
cout << "10^" << i << " = " << f << endl;
f *= 10;
}
return 0;
}

// Stuff to do: Same as for float example
```

## Integer Division vs. Decimal Division

One important distinction between type int and type double: c++ will treat the two differently when doing division. See the below program for an example.

```#include<iostream>
using namespace std;

int main() {

// This program calculates 5/3 in a few different ways.
// Notice how the types of the variables change the answer.
int x = 5;
cout << x/3 << endl;

cout << x/3.0 << endl;

double y = 5.0;
cout << y/3 << endl;

return 0;
}
```

When both the numerator and the denominator are integers, c++ will always return an integer. In other words, it will do division with remainder, then throw away the remainder. If at least one of the numerator and denominator is a double, then c++ will do decimal division.

## The Modulus Operator

Suppose that a and b are two integers. Then a%b will do the division a/b, and return the remainder.

```// Modulus example:
#include<iostream>
using namespace std;

int main() {
int dividend;
int divisor;
cout << "Input two integers: \n";
cin >> dividend >> divisor;
cout << dividend << "/" << divisor << " = " << dividend / divisor
<< " with remainder " << dividend%divisor << ".\n";
return 0;
}
```

Why do we like the modulus operator?

• Decimal-division has rounding errors. The program above gives an exact answer. Sometimes we need this.
• It can be used to check if an integer divides another. If a%b is 0, this means that b divides a exactly.
• If a%2 is 0, then a is even
• If a%2 is 1, then a is odd
• (We will learn how to write 'if' statements soon. Then we'll be able to implement the above lines in our code)
• It turns out that we use the modulus operator to create random numbers. We will probably learn this in PIC10A, but not for a while.

## Type Casting

When c++ converts a variable from one type to another, this is called 'Type Casting'. When using primitive types, c++ has type casting methods built in. Here's how the syntax works:

```TYPE1 X = VALUE;  // Here X is declared to be TYPE1
TYPE2 Y = (TYPE2)X;  // The code '(TYPE2)X' converts X to TYPE2 and returns that value```

Here's an actual program to show how type casting works:

```// Type casting example:
#include <iostream>
#include <iomanip>
using namespace std;

int main() {
cout << fixed << setprecision(4); // cout will always give 4 decimal digits
int a = 4;
double b = (double)a;
double c = 5.1203;
int d = (int)c;
cout << "a=" << a << "\n"
<< "b=" << b << "\n"
<< "c=" << c << "\n"
<< "d=" << d << "\n";
return 0;
}

/* To do:
(1) In many cases, c++ is smart enough to type-cast automatically
(i.e. without the (int) or (double) command)
Take out the (double) and (int) from the program. See what happens.
(2) Mess with those lines of cout. Add in some (int) and (double) castings
and see what happens.
*/
```

## Type Casting Problems

For each of these problems, the question is the same. What does the program output? The key is to figure out if the division is using integers or decimals.

#### Problem 1

```#include <iostream>
using namespace std;

int main() {
int a = 4;
int b = 3;
double c = a / b;
cout << c << "\n";
return 0;
}
```

#### Problem 2

```#include <iostream>
using namespace std;

int main() {
int a = 4;
int b = 3;
double c = (double)(a/b);
cout << c << "\n";
return 0;
}
```

#### Problem 3

```#include <iostream>
using namespace std;

int main() {
int a = 4;
int b = 3;
double c = ((double)a / b);
cout << c << "\n";
return 0;
}
```

#### Problem 4

```#include <iostream>
using namespace std;

int main() {
int a = 4;
int b = 3;
double c = (a / (double)b);
cout << c << "\n";
return 0;
}
```

#### Problem 5

```#include <iostream>
using namespace std;

int main() {
int a = 4;
int b = 3;
double c = (double)a/b;
cout << c << "\n";
return 0;
}
```

#### Problem 6

```#include <iostream>
using namespace std;

int main() {
int a = 4;
int b = 3;
double c = (double) a/b;
cout << c << "\n";
return 0;
}
```

All those problems have been about converting ints into doubles. Let's go the other way.

(Note: 7.9/0.9 is approximately 8.7)

#### Problem 7

```#include <iostream>
using namespace std;

int main() {
double a = 7.9;
double b = 0.9;
int c = a / b;
cout << c << "\n";
}
```

#### Problem 8

```#include <iostream>
using namespace std;

int main() {
double a = 7.9;
double b = 0.9;
int c = (int)(a / b);
cout << c << "\n";
}
```

#### Problem 9

```#include <iostream>
using namespace std;

int main() {
double a = 7.9;
double b = 0.9;
int c = (double)(a / b);
cout << c << "\n";
}
```

#### Problem 10

```#include <iostream>
using namespace std;

int main() {
double a = 7.9;
double b = 0.9;
int c = ((int)a / b);
cout << c << "\n";
}
```

#### Problem 11

```#include <iostream>
using namespace std;

int main() {
double a = 7.9;
double b = 0.9;
int c = (a / (int)b);
cout << c << "\n";
}
```

## Practice Problems

1. ```Write a program that inputs a fraction (get a numerator and denominator using cin), and outputs the same number, written as a mixed fraction.
Ex: If I input 11/5, the program should output 2 + 1/5
If I input 17/3, the program should output 5 + 2/3
You can assume that all numbers are positive (it makes the final program a bit less messy).```
2. ```Write a program that inputs a decimal number, and ouputs the integer part of that number.
Ex: If I input 5.1232309 I should output 5.```
3. ```Write a program that inputs a decimal number, and ouputs the decimal part of that number.
Ex: If I input 5.1232309 I should output 0.1232309.```

# If we have extra time

Let's play around with some other type-casting (not just ints and doubles). Write code to try to understand the following:

1. int to char, char to int
2. int to bool, bool to int
3. Any primitive type to string, or the other way around
• You should get errors here. Can you guess why?