From: glen herrmannsfeldt on 12 Jan 2010 01:38 frank <frank(a)example.invalid> wrote: (snip) > Do you know what the promotions are doing here: > i = ((double) rand () / ((double) RAND_MAX + 1) * N); > , where the i object is of type int? Well, you only need on of the (double) casts, as the other one will be done to make the types agree. I prefer, though: i=(long long)N*rand()/(RAND_MAX+1) on machines with a 64 bit (long long) and 32 bit RAND_MAX. (Though it might round differently than the (double) version. The rounding of floating point divide isn't fixed by the standard. Integer divide should consistently truncate. (I believe it still isn't specified. IEEE specifies rounded quotients, IBM hex-float specifies truncated quotients.) -- glen
From: frank on 13 Jan 2010 17:32 glen herrmannsfeldt wrote: > frank <frank(a)example.invalid> wrote: > (snip) > >> Do you know what the promotions are doing here: >> i = ((double) rand () / ((double) RAND_MAX + 1) * N); >> , where the i object is of type int? > > Well, you only need on of the (double) casts, as the other > one will be done to make the types agree. I prefer, though: > > i=(long long)N*rand()/(RAND_MAX+1) > > on machines with a 64 bit (long long) and 32 bit RAND_MAX. > > (Though it might round differently than the (double) version. > > The rounding of floating point divide isn't fixed by the > standard. Integer divide should consistently truncate. > (I believe it still isn't specified. IEEE specifies rounded > quotients, IBM hex-float specifies truncated quotients.) [OT] Glen, I think my machine has the attributes you state above, but I get overflow with that line: dan(a)dan-desktop:~/source$ gcc -std=c99 -Wall -Wextra mort6.c -o out; ./out mort6.c: In function �main�: mort6.c:43: warning: integer overflow in expression 14548979706 = 01010110101101111111101100110010 176 = 00000000000000000000000000010001 2147483648.000000 = 01001111000000000000000000000000 int by other method is -15 dan(a)dan-desktop:~/source$ cat mort6.c #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #include <limits.h> #define STRING "%7d6 = %s\n" #define E_TYPE int #define F_TYPE float #define STRING2 "%13f = %s\n" #define N 26 typedef E_TYPE e_type; typedef F_TYPE f_type; void bitstr (char *str, const void *obj, size_t n); int main (void) { int i, j, k; float g; e_type e; f_type f; char ebits[CHAR_BIT * sizeof e + 1]; char fbits[CHAR_BIT * sizeof f + 1]; srand (time (NULL)); j = rand (); e = j; bitstr (ebits, &e, sizeof e); printf (STRING, e, ebits); i = (j / (RAND_MAX + 1.0)) * N; e = i; bitstr (ebits, &e, sizeof e); printf (STRING, e, ebits); g = RAND_MAX + 1.0; f = g; bitstr (fbits, &f, sizeof f); printf (STRING2, f, fbits); k=(long long)N*rand()/(RAND_MAX+1); printf("int by other method is %d\n", k); return 0; } void bitstr (char *str, const void *obj, size_t n) { unsigned mask; const unsigned char *const byte = obj; while (n-- != 0) { mask = ((unsigned char) -1 >> 1) + 1; do { *str++ = (char) (mask & byte[n] ? '1' : '0'); mask >>= 1; } while (mask != 0); } *str = '\0'; } // gcc -std=c99 -Wall -Wextra mort6.c -o out; ./out dan(a)dan-desktop:~/source$ Your's would be line 43. I can all but guarantee that I'll go with Heathfield's version, which is: i = (j / (RAND_MAX + 1.0)) * N; , which is pretty enough to resemble fortran. [/OT] I have couple questions that can nudge this discussion towards fortran. 1) Are fortran's pseudorandoms stipulated to have a flat pdf on the unit interval? 2) Forget about the syntax, how does putting a real in the middle of a couple integers make a better random choice on an interval? -- frank
From: frank on 13 Jan 2010 17:47
steve wrote: > On Jan 11, 7:58 pm, frank <fr...(a)example.invalid> wrote: >> glen herrmannsfeldt wrote: >>> Arguments to varargs functions like printf are promoted, such >>> that (float) are converted to (double) before the call. >>> The conversion specifiers %f, %e, and %g work somewhat similarly >>> to the Fortran F, E, and G format descriptors. The width is a >>> minimum, with fields expanding as needed, with an implementation >>> defined default. >> Do you know what the promotions are doing here: >> i = ((double) rand () / ((double) RAND_MAX + 1) * N); >> , where the i object is of type int? >> >> http://c-faq.com/lib/index.html It's part of 13.16 here. > > Wrong group. Should have posted to comp.lang.c. > > -- > steve [OT] I don't intend to prattle on forever but sometimes write for the sake of the person who might be looking at the same thing. That, of course, can be me after another head injury. This might be the future of clc: #include <stdio.h> #include <stdlib.h> #include <time.h> #include <math.h> #define N 26 int main (void) { int i; char c; srand(time(NULL)); printf ("RAND_MAX is %d\n", RAND_MAX); i = nextafter((double)rand() / RAND_MAX, 0); printf ("i is %d\n", i); return 0; } // gcc -std=c99 -Wall -Wextra mort3.c -o out; ./out glibc cannot accomodate the call to nextafter as of now (1-13-2010), but I was struck by how much this resembles the fortran nearest intrinsic, which you introduced to me a couple months back. Ok, done talking, shutting up [/OT] -- frank |