#!/usr/bin/perl # Copyright (c) 2003 # John Jetmore . All rights reserved. # This code freely redistributable provided my name and this copyright notice # are not removed use strict; use Getopt::Std; my($p_name) = $0 =~ m|/?([^/]+)$|; my $p_usage = "Usage: $p_name [--help] [-if] [-p] [-s] " . "[-n] [|-]"; ext_usage(); my %opt = (); getopts('s:n:fp:i', \%opt) || mexit(2); # s - seed for srand # n - number of random numbers to produce in one run # f - produce floats instead of ints # p - specify precision - implies -f # i - increment by one on calls (rand -i 6 is 1-6, not 0-5) my $range = shift || "1-100"; my $high = 0; my $low = 0; my $seed = $opt{s} || (time() ^ ($$ + ($$ << 15))); my $count = 1; if ($opt{n}) { if ($opt{n} > 0 && $opt{n} =~ /^\d+$/) { $count = $opt{n}; } else { mexit(3, "options to -n must be an integer > 0"); } } if ($opt{p}) { if ($opt{p} <= 0 || $opt{p} !~ /^\d+$/) { mexit(4, "options to -p must be an integer > 0"); } $opt{p} = '.' . $opt{p}; } if ($range =~ /^(-?\d+)-(-?\d+)$/) { $low = $1; $high = $2; } elsif ($range =~ /^\d+$/) { if ($opt{i}) { $low = 1; $high = $range; } else { $low = 0; $high = $range - 1; } } else { mexit(1); } srand($seed); foreach (1..$count) { my $r = rand($high + 1 - $low) + $low; if ($opt{f} || $opt{p}) { $r = sprintf("%$opt{p}f", $r); } else { $r = int($r); } print $r, "\n"; #print int(rand($high + 1 - $low)) + $low, "\n"; } exit; sub mexit { my $exit = shift || 11; my $msg = shift || $p_usage; print STDERR "$msg\n"; exit($exit); } sub ext_usage { return if ($ARGV[0] !~ /^--help$/i); print "$p_usage\n\n"; print "Produce a random number\n", "Example: $p_name 6\n", "\n", "Options:\n", " -i\twhen specifying only , x will be in 1 <= x <= ,\n", "\t\tnot 0 <= x < \n", " -f\tnumbers provided as floats, not integers\n", " -p\tspecify precision (implies -f)\n", " -s\tspecify the seed to the random number generator - produce\n", "\t\tpredicable number sequences\n", " -n\tspecify an amount of random number sto be generated, one\n", "\t\tper line.", "\n", "Examples:\n", " $p_name 6\n", "\tproduces integer x such that 0 <= x < 6\n", " $p_name\n", "\tbehaves like '$p_name 100', 0 <= x < 100\n", " $p_name 1-6\n", "\t1 <= x <= 6\n", " $p_name -10-10\n", "\t-10 <= x <= 10\n", " $p_name -n 2 10-20\n", "\tproduces 2 numbers, each 10 <= x <= 20\n", "\n", "Comments:\n", " calling $p_name with just mimics perl's rand(), with\n", "\tthe exception of returning an integer. However, since this\n", "\tisn't what most people expect, specifying a range is\n", "\tinclusive on both ends.\n", " To clarify, '$p_name 6' returns a value in the set [012345],\n", "\twhile '$p_name 0-6' returns a value in the set [0123456].\n", "\n", "Exit Status:\n", " 0\tno errors occurred\n", " 1\timproper target range\n", " 2\terror parsing command line arguments\n", " 3\terror in -n\n", " 4\terror in -p\n", "\n", "Contact:\n", " proj-rand\@jetmore.net\n"; exit(0); }