From: glen herrmannsfeldt on
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
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
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