| Summary: | random() system call returning the same number on amd64 | ||||||
|---|---|---|---|---|---|---|---|
| Product: | Base System | Reporter: | moggie | ||||
| Component: | amd64 | Assignee: | freebsd-amd64 (Nobody) <amd64> | ||||
| Status: | Closed FIXED | ||||||
| Severity: | Affects Only Me | ||||||
| Priority: | Normal | ||||||
| Version: | 6.2-RELEASE | ||||||
| Hardware: | Any | ||||||
| OS: | Any | ||||||
| Attachments: |
|
||||||
|
Description
moggie
2008-03-19 22:30:00 UTC
On Wed, Mar 19, 2008 at 10:02:31PM +0000, Lewis wrote: > --- random.c begins here --- > #include <stdio.h> > #include <strings.h> > #include <stdlib.h> > #include <time.h> > #include <sys/types.h> > #include <unistd.h> > > int main(int argc, char ** argv) { > > srandom(time(0) * getpid()); > printf("time: %d\n", time(0)); > printf("pid: %d\n", getpid()); > > double r_num; This should be 'long random;', see random(3). With this change it works. Or, see below. > int i, percent = 50; > /* Constant 0x7fffffff is equal to (2**31)-1, which is the > * maximum value returned by the random() number function. > * http://web.mit.edu/answers/c/c_random_numbers.html 2008/03/19 */ > > for (i = 0; i < 100; i++) { > /*r_num = ((float) random() / (float) 0x7fffffff);*/ > r_num = random(); > > if (r_num < (percent / 100)) { > printf("random: %u - Dropped packet.\n",r_num); > } else { > printf("random: %u - Sent packet.\n", r_num); And if you want to use doubles, you should have used '%f' of '%g' here, instead of '%u'. In which case it works as well. > } > } > } > > /* Sample program output: (long r_num): time: 1205997021 pid: 59547 random: 1651842516 - Sent packet. random: 658819253 - Sent packet. random: 597332715 - Sent packet. random: 635700682 - Sent packet. random: 996321444 - Sent packet. random: 870878043 - Sent packet. random: 1977054922 - Sent packet. random: 955816479 - Sent packet. random: 367175873 - Sent packet. random: 16441391 - Sent packet. random: 1188837559 - Sent packet. random: 1906346020 - Sent packet. random: 151679052 - Sent packet. (double r_num, with '%g' in printf) time: 1205997420 pid: 59748 random: 9.87536e+08 - Sent packet. random: 1.5497e+09 - Sent packet. random: 2.13094e+09 - Sent packet. random: 1.08434e+09 - Sent packet. random: 1.94301e+09 - Sent packet. random: 1.34453e+09 - Sent packet. random: 1.77993e+09 - Sent packet. random: 1.10691e+09 - Sent packet. random: 1.95755e+09 - Sent packet. random: 1.70928e+09 - Sent packet. random: 1.66913e+09 - Sent packet. random: 1.90308e+09 - Sent packet. I think this PR can be closed. Roland -- R.F.Smith http://www.xs4all.nl/~rsmith/ [plain text _non-HTML_ PGP/GnuPG encrypted/signed email much appreciated] pgp: 1A2B 477F 9970 BA3C 2914 B7CE 1277 EFB0 C321 A725 (KeyID: C321A725) Hi, Thanks for looking at this and spotting the problem, so much time was wasted trying to figure out what was wrong :( I guess much of the confusion was caused by the same code working on i386 but not amd64 and is what prompted people to suggest to me writing a PR. Would it have been because amd64 uses different sizes of 'double' than i386 or something like that? Regards, Lewis. Roland Smith wrote: > On Wed, Mar 19, 2008 at 10:02:31PM +0000, Lewis wrote: > >> --- random.c begins here --- >> #include <stdio.h> >> #include <strings.h> >> #include <stdlib.h> >> #include <time.h> >> #include <sys/types.h> >> #include <unistd.h> >> >> int main(int argc, char ** argv) { >> >> srandom(time(0) * getpid()); >> printf("time: %d\n", time(0)); >> printf("pid: %d\n", getpid()); >> >> double r_num; >> > > This should be 'long random;', see random(3). > > With this change it works. Or, see below. > > >> int i, percent = 50; >> /* Constant 0x7fffffff is equal to (2**31)-1, which is the >> * maximum value returned by the random() number function. >> * http://web.mit.edu/answers/c/c_random_numbers.html 2008/03/19 */ >> >> for (i = 0; i < 100; i++) { >> /*r_num = ((float) random() / (float) 0x7fffffff);*/ >> r_num = random(); >> >> if (r_num < (percent / 100)) { >> printf("random: %u - Dropped packet.\n",r_num); >> } else { >> printf("random: %u - Sent packet.\n", r_num); >> > > And if you want to use doubles, you should have used '%f' of '%g' here, > instead of '%u'. In which case it works as well. > > >> } >> } >> } >> >> /* Sample program output: >> > (long r_num): > time: 1205997021 > pid: 59547 > random: 1651842516 - Sent packet. > random: 658819253 - Sent packet. > random: 597332715 - Sent packet. > random: 635700682 - Sent packet. > random: 996321444 - Sent packet. > random: 870878043 - Sent packet. > random: 1977054922 - Sent packet. > random: 955816479 - Sent packet. > random: 367175873 - Sent packet. > random: 16441391 - Sent packet. > random: 1188837559 - Sent packet. > random: 1906346020 - Sent packet. > random: 151679052 - Sent packet. > > (double r_num, with '%g' in printf) > time: 1205997420 > pid: 59748 > random: 9.87536e+08 - Sent packet. > random: 1.5497e+09 - Sent packet. > random: 2.13094e+09 - Sent packet. > random: 1.08434e+09 - Sent packet. > random: 1.94301e+09 - Sent packet. > random: 1.34453e+09 - Sent packet. > random: 1.77993e+09 - Sent packet. > random: 1.10691e+09 - Sent packet. > random: 1.95755e+09 - Sent packet. > random: 1.70928e+09 - Sent packet. > random: 1.66913e+09 - Sent packet. > random: 1.90308e+09 - Sent packet. > > I think this PR can be closed. > > Roland > On Thu, Mar 20, 2008 at 11:03:28AM +0000, Lewis wrote: > Hi, > <snip> (please don't top-post) >>> double r_num; >> >> This should be 'long r_num;', see random(3). [fixed spelling :)] >> With this change it works. Or, see below. <snip> >>> if (r_num < (percent / 100)) { >>> printf("random: %u - Dropped packet.\n",r_num); >>> } else { >>> printf("random: %u - Sent packet.\n", r_num); >> >> And if you want to use doubles, you should have used '%f' of '%g' here, >> instead of '%u'. In which case it works as well. <snip> > Thanks for looking at this and spotting the problem, so much time was > wasted trying to figure out what was wrong :( I guess much of the confusion > was caused by the same code working on i386 but not amd64 and is what > prompted people to suggest to me writing a PR. Would it have been because > amd64 uses different sizes of 'double' than i386 or something like that? I think it is rather the size of 'long', which is 32 bits on i386 and 64 bits on amd64. Compare /usr/src/sys/i386/include/_types.h and /usr/src/sys/amd64/include/_types.h I'll send you the source for a program that determines the lengths of fundamental types off-list. Roland -- R.F.Smith http://www.xs4all.nl/~rsmith/ [plain text _non-HTML_ PGP/GnuPG encrypted/signed email much appreciated] pgp: 1A2B 477F 9970 BA3C 2914 B7CE 1277 EFB0 C321 A725 (KeyID: C321A725) State Changed From-To: open->closed Not an OS bug. Roland Smith wrote: > On Thu, Mar 20, 2008 at 11:03:28AM +0000, Lewis wrote: > >> Thanks for looking at this and spotting the problem, so much time was >> wasted trying to figure out what was wrong :( I guess much of the confusion >> was caused by the same code working on i386 but not amd64 and is what >> prompted people to suggest to me writing a PR. Would it have been because >> amd64 uses different sizes of 'double' than i386 or something like that? >> > > I think it is rather the size of 'long', which is 32 bits on i386 and 64 > bits on amd64. Compare /usr/src/sys/i386/include/_types.h and > /usr/src/sys/amd64/include/_types.h > > I'll send you the source for a program that determines the lengths of > fundamental types off-list. > > Roland > Oh right, yeah that makes sense. Thanks for the source code, it is really useful, and again for your help. Regards, Lewis. |