Sunday, October 27, 2013

First prime number program

Program to calculate list of prime numbers - first 50,000 primes found in around 40 seconds.
#include <iostream>
#include <vector>

using namespace std;

//add_primes passes a complete list of prime numbers along with how many you want to add
//you can pass a vector "normally" - i.e. by value but this means that you copy the vector which is not so efficient
//you may want to pass by reference instead or also use const in order to prevent changes
//note you have to specify what type of vector as well or it just wont work at all!!
vector<unsigned long int> add_primes(vector<unsigned long int>, int);

int main()
{
    //set up some initial primes
    vector<unsigned long int> primes_list;
    primes_list.push_back(2);primes_list.push_back(3);primes_list.push_back(5);

    //ask how many primes you want to add to the list
    int extra_primes = 0;
    cout << "how many prime numbers to you want to add to the list? " << endl;
    cin >> extra_primes;

    primes_list = add_primes(primes_list,extra_primes);

    for (unsigned int i = primes_list.size()-1; i < primes_list.size();i++){
        cout << i+1 << "           " << primes_list[i] << endl;
    }

    return 0;
}

vector<unsigned long int> add_primes(vector<unsigned long int> primes, int add_ons){

    int found_new_primes = 0;
    int target;
    int primes_size;
    int primes_index;
    bool is_a_prime;

    primes_size = primes.size(); //starting number of primes
    target = primes[primes_size-1]; //starting point for search is largest prime in list


    while (found_new_primes < add_ons){

        target++; // increase target and then check if prime
        primes_index = 0; //move to start of list of primes
        is_a_prime = true; //assume target is prime until a divisor is found

        while (primes_index < primes_size){
            if ((target % primes[primes_index]) == 0) {
                is_a_prime = false; //found a divisor
                primes_index = primes_size; //found a divisor so move to the end of the primes list
            }
            primes_index++; //didnt find a divisor so move on to next prime in list
        }

        if (is_a_prime) {
            found_new_primes++;// increment as found a prime
            primes_size++; //increment as found a prime
            primes.push_back(target); //add a prime to the list
        }
    }
    return primes;
}

Friday, October 25, 2013

Introducing struct

Struct - structures - are similar to classes. Not sure of the difference. This also is the first time to use functions passing by address rather than by value - note the & syntax and that the function declaration and its definition both use the &. Note that using the const parameter can help reduce the risk of a variable being incorrectly modified when passed by reference.
#include <iostream>

using namespace std;

//Time has to be declared before its use in a function definition
 struct Time {
        int hour, minute;
        double second;
    };

//you don't put the parameter in the initial function declaration
// this function passes by address, not by value
void print_time(Time&);



int main()
{

  Time time = { 11, 59, 3.14159}; //you can assign numbers in order
  print_time(time);
    return 0;
}

Saturday, October 19, 2013

the bool type and the const qualifier

Below are a few points about bools and const.

Note that bool is an integer type but const is a qualifier, used when declaring other types - e.g. an int or a short - as a constant value.

Advantages of the const qualifier over the #define directive are that (1) you can define the type of the constant at the time, (2) you can use c++s scoping rules to limit scope if you want (3) you can use the const value to declare the size of an array.

bool is_ready = true; //normal use of bool

int ans = true; //ans assigned 1
int promise = false; //promise assigned 0 

bool start = -100; //start assigned true - any NON ZERO value is converted to true
bool stop = 0; //stop is assigned false - only ZERO is converted to false

const int MONTHS = 12; //MONTHS is symbolic constant for 12

const int toes; //value of toes is UNDEFINED!
toes = 10; //too late - you have messed up and cannot modify it now

use of char

The program below about using char shows a little about how it works, but actually this is so boring I have skipped most of this stuff.
#include <iostream>

using namespace std;

int main()
{
    char ch = 'M'; //initialize ch as a char and assign M to it
    int i = ch; //store ch - a char - as an integer value
    cout << "the ascii code for i is " << i << endl;
    cout << "add 1 to the character code - i.e. to char ch and then assign to i" << endl;
    ch = ch + 1;
    i = ch;
    cout << "the ascii code for " << ch << " is " << i << endl;

    cout << "lets use cout.put() member function to display a char: " << endl;
    cout.put(ch);
    cout << endl << " and show cout.put() using a character constant " << endl;
    cout.put('X') << endl;
    cout << " done" << endl;
    cout << "note if you use cout.put() on a cout line it gets all messed up - see this - but with no syntax error " << endl;
    cout << "this is funnny " << cout.put(ch) << " funny ehh " << endl;
    return 0;
}

hex and octal and the cout stream

Use 0x in front of a number to put in hex and just 0 for octal. I can imagine a lot of bugs appear just using octal on things like string conversions etc!

The default for the cout stream is to assume that all feeds into the stream are in decimal, however you can change the number base through feeding a "hex" or "oct" to the stream - e.g. cout << hex << 42. hex (and oct?) are both part of the std namespace.

NOTE if you use a constant in a program - e.g. cout << "year = " << 1492 << endl; - then the 1492 would be stored as an int unless there was a reason not to do so (e.g. if the value is too large or you specify otherwise using some special suffixes).

You can place letters at the end of a numeric constant to specify the type - e.g. 22022LU or 22022UL - both unsigned long; use LL for long long etc.

#include <iostream>

using namespace std;

int main()
{
  int chest = 42; //decimal integer
  int waist = 0x42; //hexadecimal integer
  int inseam = 042; //octal integer

  cout << "monsiuer cuts a striking figure" << endl;
  cout << "chest = " << chest << " 42 in decimal" << endl;
  cout << "waist = " << waist << " 0x42 in hex" << endl;
  cout << "inseam = " << inseam << " 042 in octal" << endl;
    return 0;
}

example of signed and unsigned integers

This next code highlights the difference between signed and unsigned integers and shows how you can end up "going round the houses" when you go beyond the upper limits for the different variables - with this happening for both signed and unsigned with different results.

sam is the more normal signed integer while sue is unsigned (and hence can have much higher positive values but not negative values.

IMPORTANT NOTE - for unsigned integers the above "round the houses" behavior is guaranteed, but not for unsigned integers. int main() { short sam = SHRT_MAX; unsigned short sue = sam; cout << "Sam has " << sam << " dollars ans Sue has " << sue << " dollars deposited" << endl; cout << "add usd 1 to each account" << endl << "now "; sam = sam + 1; sue = sue + 1; cout << "sam has " << sam << "dollars " << "sue has " << sue << " dollars - poor sam. Lets put to zero next" <<endl; sam = ZERO; sue = ZERO; cout << "now sam has " << sam << " dollars and sue has " << sue << " dollars" <<endl; cout << "take one dollar from each account" <<endl; sam = sam - 1; sue = sue - 1; cout << "now sam has " << sam << " dollars and sue has " << sue << " dollars" << endl; cout << "lucky sue" << endl; return 0; }

Initilization of variables with braces {}

Braces are used for initialization of arrays but can also be used for single variables. Apparently this helps prevent type conversion errors. The advantage of extending {} is to provide some consistency between initializing ordinary variables and class variables in c++ syntax.
int hamburgers = {24}; //not an array but a single value variable
int emus{7}; //you don't have to use an = sign
int rocs = {}; //if braces are empty sets to zero
int psychics{} // zero and you don't have to use an =

climits and minimum or maximum values

This code does the following:

Notes on syntax etc:

  • sizeof operator puts brackets around type - e.g. sizeof (int) - but not around variables - e.g. sizeof n_short

Note that uses expressions such as "#define INT_MAX 32767" - which, on inclusion in the header file, acts as a kind of global find and replace for the values in the #define directive. You can use your own symbolic constants using the #define directive, but this is a relic of C. The better C++ method is to use const.

If you define a variable but don't initialize it then use it in a function the value is indeterminate and ends up as the value at whatever memory location you happen to have at that time.

#include <iostream>
#include <climits>

using namespace std;

int main()
{
    using namespace std;
    int n_int = INT_MAX;
    short n_short = SHRT_MAX; //these symbols defined in climits file
    long n_long = LONG_MAX;
    long long n_llong = LLONG_MAX;

    //sizeof operator yields size of type or of variable - NOT the maximum value it looks like
    cout << "int is " << sizeof (int) << " bytes" << endl;
    cout << "short is " << sizeof n_short << " bytes" << endl;
    cout << "long is " << sizeof n_long << " bytes" << endl;
    cout << "long long is " << sizeof n_llong << " bytes" << endl;
    cout << endl;

    cout << "maximum values" << endl;
    cout << "int: " << n_int << endl;
    cout << "short: " << n_short << endl;
    cout << "long: " << n_long << endl;
    cout << "long long: " << n_llong << endl;

    cout << "minimum int value: " << INT_MIN << endl;
    cout << "bits per byte: " << CHAR_BIT << endl;

    return 0;
}