Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Random floats function

Reply
Thread Tools

Random floats function

 
 
Michel Rouzic
Guest
Posts: n/a
 
      10-14-2005

Keith Thompson wrote:
> "Michel Rouzic" <(E-Mail Removed)> writes:
> > Michael Mair wrote:
> >> Michel Rouzic wrote:

> [...]
> >> > What's wrong with the way I do my pi?
> >>
> >> 1) The C standard makes no guarantee whatsoever about the
> >> precision of the math functions from the library. So, "your"
> >> pi could be way off.
> >> 2) Your pi has to be recomputed at every function call.

> >
> > oh, ok, well, I guess it's gonna be better if I stop doing that and put
> > #define pi 3.1415926535897932 instead

>
> That's 17 significant digits; long double often has more precision
> than that.


I'm only using double precision floats, and since I heard it could take
between 15 and 17 signifiant digits...

> Using 40 decimal digits will cover anything with a mantissa up to 128
> bits, which is enough for any hardware I've ever used. Use an 'L'
> suffix to make sure you get the full precision.
>
> It's very likely that you can get away with far less precision,
> depending on the application, but using more digits than you'll ever
> need isn't a burden, and it means one less thing to worry about if
> your program misbehaves.
>
> --
> Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
> San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
> We must do something. This is something. Therefore, we must do this.


 
Reply With Quote
 
 
 
 
Michael Mair
Guest
Posts: n/a
 
      10-14-2005
Michel Rouzic wrote:
> Keith Thompson wrote:
>
>>"Michel Rouzic" <(E-Mail Removed)> writes:
>>
>>>Michael Mair wrote:
>>>
>>>>Michel Rouzic wrote:

>>
>>[...]
>>
>>>>>What's wrong with the way I do my pi?
>>>>
>>>>1) The C standard makes no guarantee whatsoever about the
>>>>precision of the math functions from the library. So, "your"
>>>>pi could be way off.
>>>>2) Your pi has to be recomputed at every function call.
>>>
>>>oh, ok, well, I guess it's gonna be better if I stop doing that and put
>>>#define pi 3.1415926535897932 instead

>>
>>That's 17 significant digits; long double often has more precision
>>than that.

>
> I'm only using double precision floats, and since I heard it could take
> between 15 and 17 signifiant digits...


This may be the case for your implementation
(platform/OS/compiler/standard library combination) but
the C standard does not guarantee it. Whether or not double
and long double are of different precision also is unspecified.

Probably you have IEEE-like doubles, so this is moot but more
digits do not hurt in _any_ respect. Whether or not it is a
good idea to multiply with a long double constant may depend
on what you want to do and your implementation.


Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
 
Reply With Quote
 
 
 
 
pete
Guest
Posts: n/a
 
      10-14-2005
pete wrote:
>
> pete wrote:
> >
> > Keith Thompson wrote:
> > >
> > > "Michel Rouzic" <(E-Mail Removed)> writes:
> > > > Michael Mair wrote:
> > > >> Michel Rouzic wrote:
> > > [...]
> > > >> > What's wrong with the way I do my pi?
> > > >>
> > > >> 1) The C standard makes no guarantee whatsoever about the
> > > >> precision of the math functions from the library. So, "your"
> > > >> pi could be way off.
> > > >> 2) Your pi has to be recomputed at every function call.
> > > >
> > > > oh, ok, well, I guess it's gonna be better
> > > > if I stop doing that and put
> > > > #define pi 3.1415926535897932 instead
> > >
> > > That's 17 significant digits; long double often has more precision
> > > than that.
> > >
> > > Using 40 decimal digits will cover
> > > anything with a mantissa up to 128
> > > bits, which is enough for any hardware I've ever used. Use an 'L'
> > > suffix to make sure you get the full precision.
> > >
> > > It's very likely that you can get away with far less precision,
> > > depending on the application, but using more digits than you'll ever
> > > need isn't a burden, and it means one less thing to worry about if
> > > your program misbehaves.

> >
> > I got all the precision of a double right here:
> >
> > /* BEGIN pi.c */

>
> Subsequent testing indicates maybe I don't
> got all the precision of a double.


I'm pretty close though.
My feeling is that since
(double)3.1415926535897932384626433832795028841971 693993751
compares equal to
4 * atan(1)
on my system, then,
4 * atan(1)
is probably correct.

The return value of pi(), seems to be low by 2 * DBL_EPSILON.
I tried adding the positive half of an extra term
in each loop in pi3, but it didn't help.

/* BEGIN pi.c output */

PI = 3.141592653589793238462643383279502884197169399375 1;
Pi = pi();
Pi2 = pi2();
Pi3 = pi3();

PI is 3.141593
Pi is 3.141593
Pi2 is 3.141593
Pi3 is 3.141593
PI - 4 * atan(1) is 0.000000e+000
Pi - 4 * atan(1) is -4.440892e-016
Pi2 - 4 * atan(1) is -4.440892e-016
Pi3 - 4 * atan(1) is -4.440892e-016
DBL_EPSILON * 2 is 4.440892e-016
Pi - Pi2 is 0.000000e+000
Pi - PI + DBL_EPSILON * 2 is 0.000000e+000

/* END pi.c output */
/* BEGIN pi.c */

#include <stdio.h>
#include <float.h>
#include <math.h>

double pi(void);
double pi2(void);
double pi3(void);

int main(void)
{
double Pi, Pi2, Pi3, PI;

PI = 3.141592653589793238462643383279502884197169399375 1;
Pi = pi();
Pi2 = pi2();
Pi3 = pi3();

puts("/* BEGIN pi.c output */\n");
puts("PI = 3.1415926535897932384626"
"433832795028841971693993751;");
puts("Pi = pi();\nPi2 = pi2();\nPi3 = pi3();\n");
printf("PI is %f\n", PI);
printf("Pi is %f\n", Pi);
printf("Pi2 is %f\n", Pi2);
printf("Pi3 is %f\n", Pi3);
printf("PI - 4 * atan(1) is %e\n", PI - 4 * atan(1));
printf("Pi - 4 * atan(1) is %e\n", Pi - 4 * atan(1));
printf("Pi2 - 4 * atan(1) is %e\n", Pi2 - 4 * atan(1));
printf("Pi3 - 4 * atan(1) is %e\n", Pi3 - 4 * atan(1));
printf("DBL_EPSILON * 2 is %e\n", DBL_EPSILON * 2);
printf("Pi - Pi2 is %e\n", Pi - Pi2);
printf("Pi - PI + DBL_EPSILON * 2 is %e\n",
Pi - PI + DBL_EPSILON * 2);
puts("\n/* END pi.c output */");
return 0;
}

double pi(void)
{
double pi, b, numerator;
unsigned denominator;

pi = 0;
numerator = 1 / 5.0;
denominator = 1;
do {
b = numerator / denominator;
numerator /= 25;
denominator += 2;
b -= numerator / denominator;
numerator /= 25;
denominator += 2;
pi += b;
} while (b > DBL_EPSILON / ;
pi *= 4;
numerator = 1 / 239.0;
denominator = 1;
do {
b = numerator / denominator;
numerator /= 57121;
denominator += 2;
b -= numerator / denominator;
numerator /= 57121;
denominator += 2;
pi -= b;
} while (b > DBL_EPSILON / 2);
return 4 * pi;
}

double pi2(void)
{
double pi, b, numerator;
unsigned denominator;

pi = 0;
numerator = 1 / 2.0;
denominator = 1;
do {
b = numerator / denominator;
numerator /= 4;
denominator += 2;
b -= numerator / denominator;
numerator /= 4;
denominator += 2;
pi += b;
} while (b > DBL_EPSILON / 4);
numerator = 1 / 3.0;
denominator = 1;
do {
b = numerator / denominator;
numerator /= 9;
denominator += 2;
b -= numerator / denominator;
numerator /= 9;
denominator += 2;
pi += b;
} while (b > DBL_EPSILON / 2);
return 4 * pi;
}

double pi3(void)
{
double pi, b, numerator;
unsigned denominator;

pi = 0;
numerator = 1 / 2.0;
denominator = 1;
do {
b = numerator / denominator;
numerator /= 4;
denominator += 2;
b -= numerator / denominator;
numerator /= 4;
denominator += 2;
pi += b;
} while (b > DBL_EPSILON / 4);
b = numerator / denominator;
pi += b;
numerator = 1 / 3.0;
denominator = 1;
do {
b = numerator / denominator;
numerator /= 9;
denominator += 2;
b -= numerator / denominator;
numerator /= 9;
denominator += 2;
pi += b;
} while (b > DBL_EPSILON / 2);
b = numerator / denominator;
pi += b;
return 4 * pi;
}

/* END pi.c */

--
pete
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      10-14-2005
pete wrote:
>
> pete wrote:
> >
> > pete wrote:
> > >
> > > Keith Thompson wrote:
> > > >
> > > > "Michel Rouzic" <(E-Mail Removed)> writes:
> > > > > Michael Mair wrote:
> > > > >> Michel Rouzic wrote:
> > > > [...]
> > > > >> > What's wrong with the way I do my pi?
> > > > >>
> > > > >> 1) The C standard makes no guarantee whatsoever about the
> > > > >> precision of the math functions from the library. So, "your"
> > > > >> pi could be way off.
> > > > >> 2) Your pi has to be recomputed at every function call.
> > > > >
> > > > > oh, ok, well, I guess it's gonna be better
> > > > > if I stop doing that and put
> > > > > #define pi 3.1415926535897932 instead
> > > >
> > > > That's 17 significant digits; long double often has more precision
> > > > than that.
> > > >
> > > > Using 40 decimal digits will cover
> > > > anything with a mantissa up to 128
> > > > bits, which is enough for any hardware I've ever used. Use an 'L'
> > > > suffix to make sure you get the full precision.
> > > >
> > > > It's very likely that you can get away with far less precision,
> > > > depending on the application, but using more digits than you'll ever
> > > > need isn't a burden, and it means one less thing to worry about if
> > > > your program misbehaves.
> > >
> > > I got all the precision of a double right here:
> > >
> > > /* BEGIN pi.c */

> >
> > Subsequent testing indicates maybe I don't
> > got all the precision of a double.


Now, as far as my system is concerned, testing indicates
that I *do* got all the precision of a double.

/* BEGIN pi.c output */

PI = 3.141592653589793238462643383279502884197169399375 1;
Pi = pi();

PI is 3.141593
Pi is 3.141593
PI - 4 * atan(1) is 0.000000e+000
Pi - 4 * atan(1) is 0.000000e+000
Pi - PI is 0.000000e+000

/* END pi.c output */

/* BEGIN pi.c */

#include <stdio.h>
#include <float.h>
#include <math.h>

double pi(void);

int main(void)
{
double Pi, PI;

PI = 3.141592653589793238462643383279502884197169399375 1;
Pi = pi();

puts("/* BEGIN pi.c output */\n");
puts("PI = 3.1415926535897932384626"
"433832795028841971693993751;");
puts("Pi = pi();\n");
printf("PI is %f\n", PI);
printf("Pi is %f\n", Pi);
printf("PI - 4 * atan(1) is %e\n", PI - 4 * atan(1));
printf("Pi - 4 * atan(1) is %e\n", Pi - 4 * atan(1));
printf("Pi - PI is %e\n", Pi - PI);
puts("\n/* END pi.c output */");
return 0;
}

double pi(void)
{
double pi, b, numerator;
unsigned denominator;

pi = 0;
numerator = 3;
denominator = 1;
do {
numerator /= 9;
b = numerator / denominator;
numerator /= 9;
denominator += 2;
b -= numerator / denominator;
denominator += 2;
pi += b;
} while (b > DBL_EPSILON / 2);
numerator = 2;
denominator = 1;
do {
numerator /= 4;
b = numerator / denominator;
numerator /= 4;
denominator += 2;
b -= numerator / denominator;
denominator += 2;
pi += b;
} while (b > DBL_EPSILON / 4);
return 4 * pi;
}

/* END pi.c */


--
pete
 
Reply With Quote
 
pete
Guest
Posts: n/a
 
      10-14-2005
pete wrote:
>
> pete wrote:
> >
> > pete wrote:
> > >
> > > pete wrote:
> > > >
> > > > Keith Thompson wrote:
> > > > >
> > > > > "Michel Rouzic" <(E-Mail Removed)> writes:
> > > > > > Michael Mair wrote:
> > > > > >> Michel Rouzic wrote:
> > > > > [...]
> > > > > >> > What's wrong with the way I do my pi?
> > > > > >>
> > > > > >> 1) The C standard makes no guarantee whatsoever about the
> > > > > >> precision of the math functions from the library. So, "your"
> > > > > >> pi could be way off.
> > > > > >> 2) Your pi has to be recomputed at every function call.
> > > > > >
> > > > > > oh, ok, well, I guess it's gonna be better
> > > > > > if I stop doing that and put
> > > > > > #define pi 3.1415926535897932 instead
> > > > >
> > > > > That's 17 significant digits;
> > > > > long double often has more precision
> > > > > than that.
> > > > >
> > > > > Using 40 decimal digits will cover
> > > > > anything with a mantissa up to 128
> > > > > bits, which is enough for any hardware I've ever used.
> > > > > Use an 'L'
> > > > > suffix to make sure you get the full precision.
> > > > >
> > > > > It's very likely that you can
> > > > > get away with far less precision,
> > > > > depending on the application,
> > > > > but using more digits than you'll ever
> > > > > need isn't a burden,
> > > > > and it means one less thing to worry about if
> > > > > your program misbehaves.
> > > >
> > > > I got all the precision of a double right here:
> > > >
> > > > /* BEGIN pi.c */
> > >
> > > Subsequent testing indicates maybe I don't
> > > got all the precision of a double.

>
> Now, as far as my system is concerned, testing indicates
> that I *do* got all the precision of a double.


And even though it seems to work on my system,
these next two lines should be switched
because of the value of the pi variable
when the loops terminate.

> } while (b > DBL_EPSILON / 2);


> } while (b > DBL_EPSILON / 4);


--
pete
 
Reply With Quote
 
Michel Rouzic
Guest
Posts: n/a
 
      10-14-2005

Michael Mair wrote:
> Michel Rouzic wrote:
> > Keith Thompson wrote:
> >
> >>"Michel Rouzic" <(E-Mail Removed)> writes:
> >>
> >>>Michael Mair wrote:
> >>>
> >>>>Michel Rouzic wrote:
> >>
> >>[...]
> >>
> >>>>>What's wrong with the way I do my pi?
> >>>>
> >>>>1) The C standard makes no guarantee whatsoever about the
> >>>>precision of the math functions from the library. So, "your"
> >>>>pi could be way off.
> >>>>2) Your pi has to be recomputed at every function call.
> >>>
> >>>oh, ok, well, I guess it's gonna be better if I stop doing that and put
> >>>#define pi 3.1415926535897932 instead
> >>
> >>That's 17 significant digits; long double often has more precision
> >>than that.

> >
> > I'm only using double precision floats, and since I heard it could take
> > between 15 and 17 signifiant digits...

>
> This may be the case for your implementation
> (platform/OS/compiler/standard library combination) but
> the C standard does not guarantee it. Whether or not double
> and long double are of different precision also is unspecified.
>
> Probably you have IEEE-like doubles, so this is moot but more
> digits do not hurt in _any_ respect. Whether or not it is a
> good idea to multiply with a long double constant may depend
> on what you want to do and your implementation.


I guess I could make it longer. Have an idea on how long is the longest
mantissa in the different existing doubles? Anyways, if I'm using pi,
it's for DSP, and since an imprecision of 10^-16 represents -160 dB,
it's way good enough. But I guess I could make it long enough for the
largest mantissa existing, doesn't cost anything but a few bytes in my
code...

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
How can i create a random array of floats from 0 to 5 in python Norah Jones Python 7 03-13-2013 05:35 AM
Re: How can i create a random array of floats from 0 to 5 in python Boris FELD Python 0 03-12-2013 05:25 PM
Math.random() and Math.round(Math.random()) and Math.floor(Math.random()*2) VK Javascript 15 05-02-2010 03:43 PM
random.random(), random not defined!? globalrev Python 4 04-20-2008 08:12 AM
Floats to chars and chars to floats Kosio C Programming 44 09-23-2005 09:49 AM



Advertisments