// Oldham, Jeffrey D. // 2000Feb01 // CS3352 // Number of Times the Net Total Crosses the Axis // We repeatedly toss fair coins, adding +1 for heads and adding -1 // for tails. We keep track of the number of times the cumulative sum // changes from positive to negative or vice versa. Touching zero and // but returning to the same side does not count. Given the number of // coin tosses, the program prints the number of crossings to standard // output. // Command-Line Argument // 1. number of trials #include #include // has EXIT_SUCCESS #include "rng.h" #include // has time() #include // for getpid() #include // for getpid() #include // has ULONG_MAX // Equilikely(a,b) returns a random integer in the range a, a+1, ..., b. template LONG Equilikely(const LONG & a, const LONG & b) { return a + static_cast((b-a+1)* Random()); } int main(int argc, char *argv[]) { if (argc != 2) { cerr << argv[0] << ": number-of-trials\n"; throw "illegal command line argument list"; } unsigned long nuTrials = strtoul(argv[1], static_cast(0), 0); if (nuTrials == ULONG_MAX) { cerr << argv[0] << ": number-of-trials out of range\n"; throw "illegal number of trials"; } // Prepare the random number generator. // erroneous code: PutSeed(time(static_cast(0)) ^ (getpid() << 15 + getpid())); PutSeed(time(static_cast(0)) ^ ((getpid() << 15) + getpid())); // Toss the coins. long sum = 0; unsigned long nuCrossings = 0; enum sign { negative, zero, positive }; sign s = zero; for (; nuTrials > 0; --nuTrials) { if (Equilikely(0,1) == 1) { ++sum; #ifdef DEBUG // cout << "tail\n"; #endif // DEBUG } else { --sum; #ifdef DEBUG // cout << "head\n"; #endif // DEBUG } #ifdef DEBUG cout << "sum = " << sum << endl; #endif // DEBUG if (sum < 0 && s == positive) { s = negative; ++nuCrossings; #ifdef DEBUG cout << "positive->negative crossing\n"; #endif // DEBUG } else if (sum > 0 && s == negative) { s = positive; ++nuCrossings; #ifdef DEBUG cout << "negative->positive crossing\n"; #endif // DEBUG } else if (s == zero) s = (sum < 0) ? negative : positive; } // Print the results. cout << nuCrossings << endl; return EXIT_SUCCESS; }