Home arrow Practices arrow Page 8 - Basic Data Types and Calculations

Numerical Functions for Integers - Practices

This article looks at some of the basic data types that are built into C++. If you're learning how to use C++, you will want to keep reading, since you'll be using these data types in all of your programs. It is taken from chapter two of the book Beginning ANSI C++: The Complete Language, by Ivor Horton (Apress, 2004; ISBN: 1590592271).

TABLE OF CONTENTS:
  1. Basic Data Types and Calculations
  2. Performing Simple Calculations
  3. Try It Out: Integer Arithmetic in Action
  4. Try It Out: Fixing the Appearance of the Output
  5. Try It Out: Using Integer Variables
  6. The Assignment Operator
  7. Incrementing and Decrementing Integers
  8. Numerical Functions for Integers
  9. Floating-Point Operations
  10. Try It Out: Floating-Point Arithmetic
  11. Try It Out: Yet More Output Manipulators
  12. Working with Characters
  13. Functional Notation for Initial Values
  14. Exercises
By: Apress Publishing
Rating: starstarstarstarstar / 14
September 08, 2005

print this article
SEARCH DEV SHED

TOOLS YOU CAN USE

advertisement

I explain functions in detail in Chapter 8, but that wonít stop us from making use of a few from the standard library before that. Letís do a quick reprise of whatís going on when you use functions and cover some of the terminology they introduce. A function is a named, self-contained block of code that carries out a specific task. Often, this will involve it performing some operation on data that you supply and then returning the result of that operation to your program. In those circumstances in which a function returns a value that is numeric, the function can participate in an arithmetic expression just like an ordinary variable. In general, a call to a function looks like this:

FunctionName(argument1, argument2, ... )

Depending on the function in question, you can supply zero, one, or more values for it to work with by placing them in parentheses after its name when you call it from your program. The values you pass to the function in this way are called arguments. Like all values in C++, the arguments you pass to a function, and the value it returns to your program, have types that you must take care to conform with in order to use the function.

You can access some numerical functions that you can apply to integers by adding an#includedirective for theheader at the beginning of your source file. This header has the same contents as the original C library header,stdlib.h. Youíll learn how each of these functions works by considering a few sample statements.

Theabs()function returns the absolute value of the argument, which can be of typeintor typelong. The absolute value of a number is just its magnitude, so taking the absolute value of a negative number returns the number with a positive sign, whereas a positive number will be returned unchanged. The value returned by theabs()function will be of the same type as the argument, for example:

int value = -20;
int result = std::abs(value); // Result is 20

The <sctdlib>header also defines thelabs()function that will also produce the absolute value of an argument of typelong. This function is there because older C programs may use it, but I suggest you just use theabs()function.

Thediv()function takes two arguments, both of typeint. It returns the result of dividing the first argument by the second as well as the remainder from the operation in the form of a structure of typediv_t. I go into structures in detail later on, so for the moment youíll just see how to access the quotient and the remainder from what is returned by thediv()function through an example:

int value = 93;
int divisor = 17;
div_t results = std::div(value, divisor);       // Call the function
std::cout << "nQuotient is " << results.quot;  // Quotient is 5
std::cout << "n Remainder is " << results.rem; // Remainder is 8

The first two statements define the variablesvalueanddivisorand give them the initial values 93 and 17, respectively. The next statement calls thediv()function to dividevaluebydivisor. You store the resulting structure of typediv_tthat is returned by the function in the variableresults, which is also of typediv_t. In the first output statement, you access the quotient fromresultsby appending the namequottoresults, separated by a period. The period is called the member access operator, and here youíre using it to access thequotmember of theresultsstructure. Similarly, in the last statement you use the member access operator to output the value of the remainder, which is available from theremmember of theresultsstructure. Any structure of typediv_twill have members with the namesquotandrem, and you always access them by using the member access operator.

Note that you could have used literals directly as arguments to thediv()function. In this case, the statement calling the function would be

div_t results = std::div(93, 17);

Theldiv()function performs the same operation as thediv()function, but on arguments of typelong. The result is returned as a structure of typeldiv_t, which has membersquotandremthat are of typelong.

CAUTION The header is inherited from C, so many implementations will have definitions of the original C functions defined outside of the stdname-space so the function names can be used without the stdqualifier. This is to allow C programs to be compiled and executed in the same environment, but you should use the functions with the stdqualifier because your code is C++.

Generating Random Numbers

Being able to generate random numbers in a program is very useful. You need to be able to build randomness into game programs, for instance; otherwise, they become very boring very quickly. Theheader defines a functionrand()that will generate random integers. To be more precise, it generates pseudo-random integers. Random numbers by definition arenít predictable, so any sequence of numbers produced by a numerical algorithm canít be truly random. It just has the appearance of being so. However, now that you understand that, youíll just refer to the numbers produced by therand()function as random numbers. Note thatrand()isnít an outstanding random number generator. For many applications, youíll probably want to use something thatís rather more sophisticated.

Therand()function return a random integer as typeint. The function doesnít require any arguments, so you can just use it like this:

int random_value = std::rand(); // A random integer

You store the integer thatís returned by therand()function here in the variablerandom_value, but you could equally well use it in an arithmetic expression, for example:

int even = 2*std::rand();

The value returned by therand()function will be a value that is from 0 toRAND_MAX.RAND_MAXis a symbol that is defined in. When you useRAND_MAXin your code, the compiler will replace it with an integer value. On my system it represents the value0x7fff, but on other systems it may have a different value. It can be up to0x3fffffff, which is the maximum integer you can store as typeint. If this was the case, then you couldnít multiply the value produced byrand()by 2, as you did previously, without running the risk of getting an incorrect result. Youíll see how you can get around this in the next chapter.

BecauseRAND_MAXis defined by a preprocessing macro (youíll learn what a preprocessing macro is in Chapter 10), it isnít within thestdnamespace, so you donít need to qualify the name when you use it. Any symbol thatís defined by a macro wonít be in thestdnamespace because it isnít a name that refers to something. By the time the compiler gets to compile the code, such a symbol will no longer be present because it will have already been replaced by something else during the preprocessing phase.

Making the Sequence Start at Random

Usingrand()as you have so far, the sequence of numbers will always be the same. This is because the function uses a default seed value in the algorithm that generates the random numbers. This is fine for testing, but once you have a working game program, youíll really want different sequences each time the program runs. You can change the seed value that will be used to generate the numbers by passing a new seed value as an integer argument to thesrand()function that is defined in, for example:

std::srand(13); // Set seed for rand to 13

The argument to thesrand()function must be a value of typeunsigned int. Although the preceding statement will result inrand()generating a different sequence from the default, you really need a random seed to get a different sequence fromrand()each time you execute a program. Fortunately, the clock on your computer provides a ready-made source of random seed values.

Thestandard library header defines several functions relating to the data and the time. Youíll just look at thetime()function here because thatís precisely what you need to obtain a more or less random seed value. Thetime()function returns a value thatís the number of seconds that have elapsed since midnight on January 1, 1970, so if you use that as a seed, you can be certain that a program will use a different seed value each time it executes. The value is returned as typetime_t, which is a type defined in the standard library to be equivalent to an integer type, usually typelong. The return type is specified as typetime_tto allow flexibility in the type of the return value in different C++ implementations. You can use thetime()function to create the seed for a random number sequence like this:

std::srand((unsigned int)std::time(0));

There are a few things that youíll have to take on trust for the moment. The argument to thetime()function here is0. Thereís another possibility for the argument, but you donít need it here so youíll ignore it. The subexpression(unsigned int)serves to convert the value returned by thetime()function to typeunsigned int, which is the type required for the argument to thesrand()method. Without this, the statement wouldnít compile. Type conversion is something else that youíll look into later.

Letís put a working example together that makes use of random number generation.

Try It Out: Generating Random Integers

Hereís the code:

 // Program 2.5 Using Random Integers #include#include#include <iostream>
#include <cstdlib>
#include <ctime>

using std::cout;
using std::endl;
using std::rand;
using std::srand;
using std::time;

int main() {
  const int limit1 = 500; // Upper limit for on set of random values
  const int limit2 = 31; // Upper limit for another set of values

  cout << "First we will use the default sequence from rand().n"; 
  cout << "Three random integer from 0 to " << RAND_MAX << ": "
       << rand() << " " << rand() << " " << rand()<< endl;

  cout << endl << "Now we will use a new seed for rand().n";
  srand((unsigned int)time(0)); // Set a new seed

  cout << "Three random integer from 0 to " << RAND_MAX << ": "
       << rand() << " " << rand() << " " << rand()<< endl;
  return 0;
}

On my system I get the following output:


First we will use the default sequence from rand().
Three random integer from 0 to 32767: 6334 18467 41

 

Now we will use a new seed for rand().
Three random integer from 0 to 32767: 4610 32532 28452


 

HOW IT WORKS

This is a straightforward use of therand()function, first with the default seed to start the sequence:

cout << "A random integer from 0 to " << RAND_MAX << ": "
     << rand() << endl;

Each call torand()returns a value that will be from 0 toRAND_MAX, and you call the function three times to get a sequence of three random integers.

Next, you set the seed value as the current value of the system clock with this statement:

srand((unsigned int)time(0)); // Set a new seed

This statement will generally result in a different seed being set each time you execute the program. You then repeat the statement that you executed previously with the default seed set. Thus, each time you run this program, the first set will always produce the same output, whereas with the second set, the output should be different.



 
 
>>> More Practices Articles          >>> More By Apress Publishing
 

blog comments powered by Disqus
escort Bursa Bursa escort Antalya eskort
   

PRACTICES ARTICLES

- Calculating Development Project Costs
- More Techniques for Finding Things
- Finding Things
- Finishing the System`s Outlines
- The System in So Many Words
- Basic Data Types and Calculations
- What`s the Address? Pointers
- Design with ArgoUML
- Pragmatic Guidelines: Diagrams That Work
- Five-Step UML: OOAD for Short Attention Span...
- Five-Step UML: OOAD for Short Attention Span...
- Introducing UML: Object-Oriented Analysis an...
- Class and Object Diagrams
- Class Relationships
- Classes

Developer Shed Affiliates

 


Dev Shed Tutorial Topics: