473,396 Members | 2,158 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Re: Lotto 7/45


[I've added comp.lang.c and set followups there since it is clear that
C people to check this over.]

Richard Heathfield <rj*@see.sig.invalidwrites:
Ben Bacarisse said:

<snip>
>You warn the OP not to combine the first and second loops, but why not
combine the second and third? Having swapped the first x numbers, you
can stop -- that array prefix will not change.

Good spot.
>The OP does not even
like calling rand() 7 times, so it seems churlish to call it another
38 times!

Perhaps I misunderstood the OP, but I thought he was doing this:

a) set count to 0
b) pick a random number in the range 1 to 45
c) if we haven't seen this number before
d) store it and increment the counter
e) end if
f) unless count is now 7, go round again from (b).

This has the potential to call rand() a great many more times than
7.
Yes, but the OP complained about making even 7 calls, that's all.
(Actually the expected number of calls with the above algorithm is
only a shade over 7.5, but that's not why I said 7).
>There is also a danger in the almost canonical:

int r = (n - i) * (rand() / (RAND_MAX + 1.0)) + i;
int t = arr[r];

This is not portable in the comp.lang.c sense but is fine in most
practical situations. The problem is that if int is 64 bits, the
calculation can yield an r that is out of bounds.

How? Remember that n is the number of balls in the lottery, so
pragmatically speaking it will be a not-very-large number. The expression
rand() / (RAND_MAX + 1.0) will give us a value in the range 0 to 1. So
we've got a not-very-big number less a certainly-no-bigger number,
multiplied by a value in the range 0 to 1 (making the number probably
smaller and certainly no bigger), and then adding a not-very-big number. I
am at a loss to see how this can give us an invalid value for r, and I
await enlightenment.
The code relies on the floating point division never actually being 1
but on a system with a 64 bit int, RAND_MAX could be as large as a
typical implementation's LLONG_MAX. On my Intel x86 gcc system, this
program

#include <stdio.h>
#include <limits.h>

#define RAND_MAX LLONG_MAX

long long int rand(void) { return RAND_MAX; }

int main(void)
{
int r = 45 * (rand() / (RAND_MAX + 1.0));
printf("%d\n", r);
}

prints 45. It prints 45 for rand() values from RAND_MAX all the way
down to RAND_MAX - 0x1ff [1]. I don't think this is a gcc bug, though
I am not enough of a FP expert to know if this behaviour is
conforming.

Lowly double simply runs out of precision with very big integers, and
the division yields 1 exactly. Change the 1.0 to 1.0L and the problem
goes away. (I used 45, because that is the 'n' used in the OP's
lotto, but the problem has nothing to do with that number.)

For double precision floating point, you don't need integers anything
like this big. If plain int has INT_MAX == RAND_MAX ==
0x20000000000000 then, with the same double precision implementation,
I get 45 as output again but this time, of course, only in the one
case where rand() returns RAND_MAX.

Thinking it over, C90 is not safe. All this seems allowed on any C
implementation unless there is some nice guarantee about floating
point division that gcc is ignoring (and that I've missed).
>You can also get
burnt if you use a system with poor double precision arithmetic,
though I am not 100% sure how bad the C standard allows it to get.

Ten digits of precision ought to be enough for anybody. :-)
But with 10 digits even lower RAND_MAX values give problems. 10
digits is very close to the precision that can show this behaviour
with plain 32 bit signed ints (though I can't be sure).

[1] Not many. In fact few enough that

int r;
do r = n * (rand() / (RAND_MAX + 1.0)); while (r == n);

will be safe and fast.

--
Ben.
Aug 7 '08 #1
2 1638
On Aug 7, 2:52 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
#include <stdio.h>
#include <limits.h>

#define RAND_MAX LLONG_MAX

long long int rand(void) { return RAND_MAX; }

int main(void)
{
int r = 45 * (rand() / (RAND_MAX + 1.0));
printf("%d\n", r);
}

prints 45.
Isn't it undefined behaviour to define your own
functions with external linkage and with the same
name as standard library functions (even if the
associated header is not included) ?

Aug 8 '08 #2
Old Wolf <ol*****@inspire.net.nzwrites:
On Aug 7, 2:52 pm, Ben Bacarisse <ben.use...@bsb.me.ukwrote:
> #include <stdio.h>
#include <limits.h>

#define RAND_MAX LLONG_MAX

long long int rand(void) { return RAND_MAX; }

int main(void)
{
int r = 45 * (rand() / (RAND_MAX + 1.0));
printf("%d\n", r);
}

prints 45.

Isn't it undefined behaviour to define your own
functions with external linkage and with the same
name as standard library functions (even if the
associated header is not included) ?
Yes. The post was about what rand() might do so I allowed myself to
keep the name. Imagine the #define and definition of rand() in a
comment and #include <stdlib.hinstead if it helps.

The only interesting point being that I think the frequently seen
expression:

int r = max * (rand() / (RAND_MAX + 1.0));

can leave r == max if int is big enough or the floating point
arithmetic imprecise enough.

--
Ben.
Aug 8 '08 #3

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

12
by: sathia | last post by:
Hi, I have this table:   CREATE TABLE `osservatorio` (   `id` int(10) unsigned NOT NULL auto_increment,   `testo` varchar(255) NOT NULL default '',   `parent` int(11) default NULL,...
0
by: Rogue 9 | last post by:
Hi All, I am developing a program called oop_lb.py and it's package structure is as below: oop_lb | -------------------------------------- | | | analysis process ...
0
by: August1 | last post by:
This is a follow up to using these functions to produce lottery numbers to an outfile, then read the numbers from the file to the screen. Although other methods are certainly available. ...
4
by: Maxi | last post by:
I have posted my question on my website as the alignment in this post goes for a toss. The text editor wraps up the data in the next line by default and because of which I am not able to copy my...
8
by: Maxi | last post by:
There is a lotto system which picks 21 numbers every day out of 80 numbers. I have a table (name:Lotto) with 22 fields (name:Date,P1,P2....P21) Here is the structure and sample data: ...
0
by: Veerle | last post by:
Hi, On the website of the Belgian lottery, you can download an excel sheet with lottery results (the winning numbers) over the years and an excel sheet with financial results (the winnings) over...
7
by: mariiikar | last post by:
K. I'm kinda totally lost on how to go about this.... Here's the Question: ------------------------------ Write a program that will store a list of six Lotto numbers and then invites the user...
2
by: Cainnech | last post by:
Hi guys, It's me again. Arrays are a mindbuster for me. I'm stuck again but I can't see the error. <HTML> <HEAD> <SCRIPT> var lotto = ; var winst = ;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.