CS110_04a_random - EECS110: 4a Randomness; Functions...

Info iconThis preview shows page 1. Sign up to view the full content.

View Full Document Right Arrow Icon
This is the end of the preview. Sign up to access the rest of the document.

Unformatted text preview: EECS110: 4a Randomness; Functions Libraries Jack Tumblin jet@cs.northwestern.edu , Random numbers Random == completely unpredictable, entirely nondeterministic. Impossible to predict next value from previous values. Program == a set of rules; always repeatable. A true `Random Number' program? Impossible! Instead: pseudo-random sequences (looks random) Interesting Exceptions: Some mainframes, supercomputers used a tiny radioactive source and counted time between particle emissions. A true Poisson-distributed random variable, guaranteed by quantum mechanics! Others used electronic noise (`static') generators to re-set a timer (susceptible to interference) 1996: Silicon Graphics aimed video cameras a `Lava Lamps' and measured evolving shapes. Others put microphones in a sand hourglass, etc. How? Use the C function int rand(void); returns value is an integer between 0 and RAND_MAX Defined in stdlib.h Pseudo-Random Example Print 10 seemingly-random integers between 0 and RAND_MAX #include<stdio.h> #include<stdlib.h> int main(void) { int i; for (i=0; i<10; i++) // for(init; cond; step) { printf("%d\n", rand()); } return 0; } // for printf() // for rand() Pseudo-Random Sequence How does it work? Result of previous rand()call is the (hidden) input to the bit-scrambling process that makes the next rand() answer. The initial hidden input value is called the `seed'. s rand() 41 (seed) 41 rand() 18467 18467 rand() 6334 ... 6334 C's "Random" numbers (aren't really random) REPEATABLE! Same seed, same number of calls to rand() will give the same result every time. This is WONDERFUL for debugging: all problems are exactly repeatable But usually bad for the appearance of randomness. Need to be able to SET the seed value... rand() Seed-Setting The initial value (s) is called the seed. Calls to rand()from the same seed give the same sequence. Seed-setting function is found in stdlib.h : void srand(int seed); To guarantee the same pseudo-random sequence every time your program runs, set seed to a constant value (e.g. srand(10); ) Use a different seed each time to guarantee a different pseudo-random sequence (but how?...) Set a Different Seed ? How can we set a different seed every time our program runs? Use the computer's time-of-day clock: Built-in C function to report current time found in time.h file; to access it use #include <time.h> The time(NULL) function call returns a time value, but is not an int Must cast the returned value before use: srand( (int) time(NULL)); /* new rand seed */ Careful! only need to call this ONCE in program; don't put it inside a loop. Try it as 1st statement of main(). Integer Range-Setting How can we get a selected range from rand()? rand() Example: simulate dice-rolling: find a random number between 1 and 6 Example: guess day of 1st Chicago snowfall randomly choose [1,...,7] for [Monday,...,Sunday]. One answer: use the modulus operator x = rand()%6; x = rand()%6 +1; // // 0 <= x <= 5 1 <= x <= 6 Integer Range-Setting How can we get a selected range from rand()? rand() Example: simulate dice-rolling: find a random number between 1 and 6 Example: guess day of 1st Chicago snowfall randomly choose [1,...,7] for [Monday,...,Sunday]. 6 choices beginning at 0 One answer: use the modulus operator x = rand()%6; x = rand()%6 -3; // 0 <= x <= 5 // -3 <= x <= 2 OFFSET: 6 choices beginning at -3 Floating-Point Range Setting How can we get random real numbers in a selected range? double randspan(double lo, double hi) /*==================================================== *Return a randomly-chosen floating-point number that * falls between the floating-point numbers (lo, hi). */ { double var01, span, mid; // local variables var01 = (double)rand() / (double)RAND_MAX; // Normalize: 0.0 <= var01 <= 1.0 span = hi lo; // distance from lo to hi mid = lo + span*var01; return(mid); } Floating-Point Range Setting How can we get random real numbers in a selected range? double randspan(double lo, double hi) /*==================================================== *Return a randomly-chosen floating-point number that * falls between the floating-point numbers (lo, hi). */ { double var01, span, mid; // local variables var01 = (double)rand() / (double)RAND_MAX; // Normalize: 0.0 <= var01 <= 1.0 span = hi lo; // distance from lo to hi mid = lo + span*var01; Map rand() output return(mid); } to 0.0 1.0 range Floating-Point Range Setting How can we get random real numbers in a selected range? double randspan(double lo, double hi) /*==================================================== *Return a randomly-chosen floating-point number that * falls between the floating-point numbers (lo, hi). */ Find distance on real { number local variables line that double var01, span, mid; // rand() should span var01 = (double)rand() / (double)RAND_MAX; // Normalize: 0.0 <= var01 <= 1.0 span = hi lo; // distance from lo to hi mid = lo + span*var01; return(mid); } Floating-Point Range Setting How can we get random real numbers in a selected range? double randspan(double lo, double hi) /*==================================================== *Return a randomly-chosen floating-point number that * falls between the floating-point numbers (lo, hi). */ Choose a number { within that distance double var01, span, mid; // local variables range; var01 = (double)rand() / (double)RAND_MAX; // Normalize: 0.0 <= var01 <= 1.0 span = hi lo; // distance from lo to hi mid = lo + span*var01; return(mid); Offset the range to } begin at lo and end at hi (Recall) loops, rand(), srand: Practice problems 1. Write a program that prints out all integers from 1 to 100 that are divisible by both 6 and 7 2. Write a program that prints out all integers from 1 and 100 that are divisible by 6 or 7 but not both. 3. Write a program that accepts an integer and prints out a list of all its prime divisors. 4. Rewrite Problem 3 without using the modulus operator (%). (Recall) Function Prototypes Define function's name, inputs, and output type. name inputs It is all you need to know to use a function. Some functions we use seem hidden... #include<stdio.h>, other `.h' files These `header' files are full of function prototypes stdio.h has the prototypes (but not the function bodies) for printf(), scanf(), and many more. Where are the function bodies? In a `library' file hidden somewhere ... Why? Security; Consistency; Encapsulation; Nesting In Files: Modules (not in book?!?!) A final stage of instruction nesting in C: Expression: one operator and its terms EX: a+b b=5 Statement: terminated expressions EX: c = a+5; Function: a named block of statements EX: printf() Module: a group of related functions EX: stdio.h Modules: Why Bother? After a while, your main.c file gets crowded: too many function prototypes and bodies No organization or grouping of functions Solution: Put function prototypes into myfunc.h file, and replace them with #include "myfunc.h" Put function bodies into myfunc.c file, and add that file to your Visual C++ Project. IMPORTANT DEBUG HINT: Trouble with modules? Go backwards: put all functions in main.c, make them work, THEN make/test modules one-at-a-time. What's the Big Idea? Interfaces Interface==a shared boundary between Interface two separate entities: Water[surface]air, human[knob]radio, programmer[.h file]client Using a function (e.g. printf(), scanf() ) is unrelated to writing that function: Keep them separate and independent! Gather sets of similar functions into `libraries', use `Black box' idea ; hide internal workings of a library, just as we did with internals of a function. The big idea: Interfaces in C: Header File == the interface== .h file; file a fixed, reliable boundary between your code and a library of functions. All you need to know. holds a list of function prototypes Defines all function names, inputs, outputs Heavily commented (`directions for use'). Library ==easy-to-use, already-written-anddebugged collections of compiled C functions. Write your own C Interface A well-designed interface is: consistent, with a clear unifying theme (Example: graphics.h, math.h, windows.h, ...) simple (hide complex details from the user) sufficient, complete (does all parts of task) general (helps any programmer) stable (interface stays the same even as you improve/change implementation) Write your own C Interface Step 1: Create an interface file myfuncs.h of function prototypes and comments. Step 2: Write all the function implementations in the separate file myfuncs.c Step 3: To use any of these functions in main(), just #include the interface file: #include "myfuncs.h" ( Step 4: (MUCH later) convert myfuncs.c to myfuncs.lib to hide & control source code. Example: glut32.lib ) Interface File: Syntax Contents of a header file: #ifndef _funcs_h #define _funcs_h any required #include lines any constant definitions any type definitions /*(more about this later)*/ function prototypes #endif `Wrapper': more compiler directives; "include only once" Good comments are CRUCIAL here! NESTED LIBRARIES allowed! Your library file (myfuncs.c) may need to use other functions such as printf(). Put include statements #include <stdio.h> inside interface (myfuncs.h), ( not myfuncs.c) CAUTION! `circular' includes will not work! /* * my1.h file */ #include "my2.h" ... /* * my2.h */ file #include "my1.h" ... ...
View Full Document

This note was uploaded on 10/05/2011 for the course COMPUTER S 110-1 taught by Professor Tumblin during the Spring '11 term at Northwestern.

Ask a homework question - tutors are online