• 0

[C] random double between 0 and 1


Question

Hello all,

Im a newbie to C and I am not figuring out how to make a function that will generate a double between 0 and 1...

I KNOW NOTHING ABOUT C but managed to get a hello world work...

I tries this function but i think it's not working properly:

float_number = (float) rand()/RAND_MAX;

as when i try to display the num with this forloop it's getting me huge negative or positive numbers

		for(i = 0; i < 500; i++){
			printf("%d\n",  float_number);
		}

another thing, what should i add to the code so i dont allow the program to exit directly after execution and so the command prompt stays opened so i can see the results?

Thanks in advance.

Elio

Link to comment
https://www.neowin.net/forum/topic/980266-c-random-double-between-0-and-1/
Share on other sites

21 answers to this question

Recommended Posts

  • 0

You should use "%f" for floating point numbers, not "%d."

On the second question, some IDEs will prevent the program from closing immediately. Otherwise something simple like fgetc(stdin) will work.

Thanks for the fgetc(stdin) it worked...

the random number gives always the same number :s

think i passed through this earlier today on google.. will double check...

10x anw

  • 0

That is because by default the rand function is seeded with 0. Check this out: http://www.cplusplus.com/reference/clibrary/cstdlib/srand/ the most popular solution is to seed it with the system time. That should give you different pseudo random sequences for each run.

  • 0

for(i = 0; i < 500000; i++){
			double_number = (double) rand()/RAND_MAX;
				srand (time(NULL)); // this is used to seed the random number by the system time
			printf("%f\n",  double_number);
		}

The thing is i need to generate a huge number of random doubles in a for loop...

i hate 2 problems:

  1. Time interval in the loop is verry small, the number is slightly changing every one second which is bad
  2. The generated numbers are very closed to each other,,, and i dont want that :(

OKay fixed it :)

\

for(i = 0; i < 50; i++){
			double_number = (double) rand()/RAND_MAX;
				srand (time(NULL)+rand()); // this is used to seed the random number by the system time
			printf("%f\n",  double_number);
		}

  • 0

Call srand(time(NULL)) once before the loop. This will continue to generate random numbers. You don't need to call it every time.

Also, since you're using double precision instead of single, you really should use "%Lf" in the printf statement.

Okay thanks...

It's actually my first C program :-)

  • 0

I KNOW NOTHING ABOUT C

Cool. So maybe one of the first things that you should learn is that rand() does not, under any stretch of your imagination, generate a random number. Pound that idea into your head. It doesn't matter what you seed it with, either, but seeding with the current time is what everybody does and it almost always causes a problem at some point. Someone could use a number of methods to predict, both ahead of time and after the fact, the exact 50 doubles that your function would generate. If you run your program more than once within 1 second, it will generate the same sequence of 50 doubles. Or if two people run your program within a second of each other they will both generate the same sequence. If you need a range of doubles other than 0.0 to 1.0, I guarantee you'll do it wrong. Your rand() function will start to repeat itself after about 32,000 calls. There are plenty of other pitfalls. These things may or may not matter to you, but the reality is that this kind of thing is a bit complicated.

There is no good cross-platform way to reliably generate random numbers without using C++ or using a C library. This is especially true if you're looking for something like numbers that are unpredictable, has a special distribution (normal, uniform, poisson, etc), want them in a range that's not evenly divisible by the size of the random numbers you are generating, or if you need a secure seed value.

If you're able to use C++ (which will compile C code as well), modern compilers support a set of random number generators that can generate random numbers in various distributions (random, normal distribution, even distribution, etc) using various algorithms (including unpredictable sources), with larger periods (the amount of times before the RNG starts repeating). That way you don't have to worry about clipping your range or accidentally creating an uneven probability for certain numbers (like lots of people do with "rand() % SOME_NUMBER"). For example, you can do this to reliably generate a random (meaning each double has an equal probability of being generated) double between 0.0 and 1.0, inclusive:

mt19937 engine(YOUR_SEED);
uniform_real<double> distribution(0.0, 1.0);
variate_generator<mt19937&, uniform_real<double> > gen(engine, distribution);

for (int i = 0; i < 50; i++)
    double rndDouble = gen();

You can generate more values than there are atoms in the visible universe before that generator repeats itself. Then getting other ranges, distributions, generators, or engines is as easy as switching them in.

Regardless of whether you can use C++, if you need a seed value, then please seed your rand function with something other than time(NULL); you can find countless forum posts where using time-based seeds causes some problem. On linux, just read a random value from "/dev/urandom". On Windows, you can use rand_s (which makes a call to the cryptographic RNG function, which is stupidly-named "SystemFunction036") if speed is a concern or use "rand_s" directly and simply skip the seeding process (since a cryptographic RNG, by definition, doesn't need a user-supplied seed value).

  • Like 2
  • 0

another thing, what should i add to the code so i dont allow the program to exit directly after execution and so the command prompt stays opened so i can see the results?

you can use

system("PAUSE");

which is a call to the PAUSE instruction you can also call in cmd

  • 0

Okay thanks everyone...

I managed to make the assignment work...

it is part of the parallel programming course and we are trying to calculate the value of PI based on the mote carlo (somthing like that :p lol ) method...

and i need to take 100% random numbers.

The thing is we did it sequentially just to get used to C as we are JAVAists

and the next step would be parallelizing it...

thanks again

  • 0

//check if a point is inside a circle
		for( i=0; i<number_of_points; i++){   //number_of_points = 99999999;
			double current_x = points_xes[i];
			double current_y = points_yies[i];    //is this causing huge memory usage?


			if((current_x * current_x) + (current_y * current_y) <= 1){
				count_inside++;
			}else{
				count_outside++;
			}

I THINK THIS PART OF CODE IS USING MY RAMS... AFTER EXECUTION THE RAM USAGE INCREASES BY 1 GB... do you think this loop is the reason? as i have huge number of points and i'm creating 2 new doubles in each iteration?

how can i fix this?

Should i set them to null in the end of the loop and later "garbage collect them"?? (is there garbage collection in c?)

thanks

  • 0

If you're storing almost 100 million doubles in memory, yes that will tend to use up a lot of memory at at least 8 bytes a pop.

There is garbage collection in C, but it's manual. You use the free(my_ptr) function where my_ptr is something that was created using malloc or calloc (like the huge arrays you're using). You don't perform garbage collection on regular doubles. It also shouldn't be recreating them, but you can move the double current_x to oustide the loop and then just do current_x = if somehow that's the case.

  • 0

You are not creating two new doubles each iteration. You are re-using the same doubles that live on the stack.

However, assuming the code works correctly, points_xes and points_yies contain at least 100 million elements. Assuming they are doubles, and a double is 8 bytes, that is 2 x 8 bytes x 100 million = 1600MB. The memory allocation happens before the loop, in some code you haven't shown here.

  • 0

After seeing that 100,000,000 iteration loop, I'm not sure we want to see the other code. I also don't want to know if he's stack-allocating 100,000,000-length double arrays.

#include<stdio.h>
#include<stdlib.h> //now i can use rand()

#include<time.h>
#include<string.h>


int i;
double double_number;
int number_of_points = 99999999;
double points_xes[99999999];
double points_yies[99999999];
int count_inside = 0; //count the number of points inside the circle
int count_outside = 0; //count the number of points outside the circle
double percentage_p_inside = 0; //percentate of the points inside the circle
double PI = 0; //the found value of PI


time_t start_time;
time_t end_time;




main()
{

		printf("Welcome to computing pi!, Elio's first C program.");
		printf("\n\nComputing PI based on %d",number_of_points);
		printf(" points.\n");

		start_time = time (NULL); //get the start time

		srand (time(NULL)+rand()); // this is used to seed the random number by the system time
		//computing the first number_of_points point and considering them as the "X" value for each point
		for(i = 0; i < number_of_points; i++){
			double_number = (double) rand()/RAND_MAX;

			points_xes[i] = double_number;
			//printf("%Lf\n",  double_number);
		}


		//computing the second number_of_points point and considering them as the "Y" value for each point
		for(i = 0; i < number_of_points; i++){
			double_number = (double) rand()/RAND_MAX;

			points_yies[i] = double_number;
			//printf("%Lf\n",  double_number);
		}



		//check if a point is inside a circle
		for( i=0; i<number_of_points; i++){
			double current_x = points_xes[i];
			double current_y = points_yies[i];


			if((current_x * current_x) + (current_y * current_y) <= 1){
				count_inside++;
			}else{
				count_outside++;
			}
		}



		printf("\nNumber of points inside: %d",count_inside);
		printf("\nNumber of points outside: %d", count_outside);

		//calculate the percentage of points inside the circle
		percentage_p_inside = (double)(count_inside)/(count_inside + count_outside);
		printf("\nPercentage of points inside the circle: %Lf",percentage_p_inside);


		PI = percentage_p_inside * 4;
		printf("\n\nPI = %Lf", PI);

		end_time = time(NULL);

		printf("\nPI calculated in: %d",(end_time-start_time));
		printf(" seconds.");

		fgetc(stdin); // just to avoid closing the command prompt after the excecution of the code.
}


here is the rest of the code...

I know it could be very bad in term of design but i told u it's my first c program and i done it all by myself.. they didnt give us any tutorial

it's just a university small hw... :p

10x

238423149.jpg

  • 0

I'm surprised the program even compiles or runs, although I've never tried putting that much data in static storage so I don't really know. Maybe someone with better knowledge of C can provide some precisions. Anyway, when you need large amounts of memory, use the heap (malloc() in C, new in C++). This will allow you to free it at runtime when you are done with it (free() in C, delete in C++), whereas static storage remains until program termination. See here for examples (in C++).

That being said, even using dynamic memory allocation isn't the way to go. Your basic problem here is that you try to generate all your points first, and then perform your statistical analysis on the whole bunch. What you could do, and it would use almost no memory, is to only work with a single point at a time, i.e. (pseudocode):

int pointsInsideCount = 0;
int pointsOutsideCount = 0;

for (number of points) { 
    double x = generateRandomDouble();
    double y = generateRandomDouble();
    if ((x, y) is inside circle) {
        ++pointsInsideCount;
    }
    else {
        ++pointsOutsideCount;
    }
}

This only ever uses the same two doubles, on the stack. 8 temporary bytes vs 1600 static MBs. Plus here it doesn't matter how many points you want, it'll take longer but it'll never use up any additional memory. :yes:

  • 0

I'm surprised the program even compiles or runs, although I've never tried putting that much data in static storage so I don't really know. Maybe someone with better knowledge of C can provide some precisions. Anyway, when you need large amounts of memory, use the heap (malloc() in C, new in C++). This will allow you to free it at runtime when you are done with it (free() in C, delete in C++), whereas static storage remains until program termination. See herefor examples (in C++).

That being said, even using dynamic memory allocation isn't the way to go. Your basic problem here is that you try to generate all your points first, and then perform your statistical analysis on the whole bunch. What you could do, and it would use almost no memory, is to only work with a single point at a time, i.e. (pseudocode):

int pointsInsideCount = 0;
int pointsOutsideCount = 0;

for (number of points) { 
    double x = generateRandomDouble();
    double y = generateRandomDouble();
    if ((x, y) is inside circle) {
        ++pointsInsideCount;
    }
    else {
        ++pointsOutsideCount;
    }
}

This only ever uses the same two doubles, on the stack.

yes u're right...

wat a bad design i was using :s loool

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Google is opening the world's first AI museum in Los Angeles by Ivan Jenic Image via: Google Ever since AI image generators went mainstream, the debate over whether AI-generated art is real art hasn't let up. Those who don’t consider AI to be art say that if a machine does the creating and anyone can prompt it, there’s no skill involved, and therefore no art is produced. The counter-argument is equally persistent, as defenders of AI-generated artworks often claim that AI is just a tool, and that every major technological breakthrough, like the camera or the computer, was met with the same skepticism before eventually being accepted as a legitimate creative medium. Google’s position in this debate is clear. Which is no surprise, as the company is investing billions in AI infrastructure. And now, in efforts to encourage people to use its AI even more, Google is opening Dataland on June 20, which it's calling the world's first AI arts museum. Located inside The Grand LA, a Frank Gehry-designed building in Los Angeles, the museum spans 25,000 square feet. The museum is built around a collaboration with media artist Refik Anadol, who has worked with Google since 2016. The inaugural exhibition is called Machine Dreams: Rainforest, and is powered by an AI model trained on “an extensive dataset of the natural world.” It generates 1.2 billion pixels of visuals in real time and reacts to visitors dynamically. The space also generates soundscapes, real-time emotion sensing, and algorithmically produced scents. Image via: Refik Anadol Studio / Google Google says that the museum is powered by its Gemini models, which run on Google Cloud. So, everything is generated inside one of Google’s AI data centers and is streamed to the museum. Alongside the museum opening, Google Arts & Culture is funding an AI Artist Residency, giving four artists $25,000 grants each, along with mentorship from Refik Anadol Studio and access to Google's machine learning tools. Their work will be shown at Dataland and on the Google Arts & Culture website later this year. Google’s AI museum will undoubtedly initiate a fired-up debate on social media, and we can’t wait to see the first reactions. Via: Smithsonian Magazine
    • Calling GTA 6 overhyped crap doesn’t make you edgy, it just makes you sound like someone who hasn’t enjoyed anything since the PS2 era.
    • I’m not arguing whether Rockstar likes money. Obviously, they do, they’re a business. I’m saying this isn’t new. They’ve always launched console first. This is just how Rockstar operates.
    • I'm not sure how old the school is, but they've been doing this since GTA 3. Back in those days we'd be lucky for game companies to release on the PC at all. And with the current state of Sony (or Microsoft) their gaming wing won't be getting a penny from me.
    • We now know when and how the Universe may truly end by Sayan Sen Image by Marek Pavlík via Pexels| Not representative A study by physicist Henry Tye of Cornell University suggests that the universe may not expand forever. Instead, it could eventually stop expanding, begin contracting and end in a "Big Crunch" roughly 20 billion years from now. The research, published in the Journal of Cosmology and Astroparticle Physics, was conducted by Tye, Horace White Professor of Physics Emeritus at Cornell University. Using recent observations from major dark-energy surveys, Tye and his collaborators developed a cosmological model that predicts the universe could have a total lifespan of about 33 billion years. Since the universe is currently estimated to be 13.8 billion years old, the model places it near the midpoint of its existence. According to Cornell University's summary of the research, the study centers on the cosmological constant, a term introduced by Albert Einstein in his theory of general relativity. In modern cosmology, the cosmological constant is commonly used to describe the simplest form of dark energy, the unknown phenomenon believed to be driving the accelerating expansion of the universe. "For the last 20 years, people believed that the cosmological constant is positive, and the universe will expand forever," Tye said in a Cornell University news release. "The new data seem to indicate that the cosmological constant is negative, and that the universe will end in a big crunch." The study draws on data from the Dark Energy Survey (DES) and the Dark Energy Spectroscopic Instrument (DESI), two major projects designed to investigate the nature of dark energy. According to Tye, recent observations suggest that dark energy may not behave exactly like a simple cosmological constant. To account for those observations, Tye and his collaborators proposed a model involving an extremely light hypothetical particle that evolves over time. In their calculations, this produces a negative cosmological constant and leads to a future collapse of the universe. The model predicts that cosmic expansion would continue for approximately another 11 billion years before reaching a maximum size, after which the universe would begin contracting and eventually collapse. Scientists have long debated how the universe might end. As explained in an article published in The Conversation by Stephen DiKerby of Michigan State University, several possibilities have been proposed. If dark energy remains constant and positive, the universe could continue expanding indefinitely, gradually becoming colder, darker and more diffuse in a scenario often called the "heat death" of the universe. Other theoretical possibilities include a Big Rip, in which cosmic expansion accelerates so dramatically that galaxies, stars and even atoms are torn apart, or a Big Crunch, in which expansion reverses and the universe collapses back into an extremely dense state. DiKerby notes that the Big Crunch idea itself is not new. What distinguishes Tye's work is that it attempts to use current observational data to estimate when such a collapse might occur and how it could unfold. Much of the universe's long-term evolution remains uncertain. According to current astrophysical understanding, stars will continue to form and die for billions of years. The Sun, for example, is about halfway through its expected lifespan. Galaxies are also expected to continue merging; the Milky Way and Andromeda galaxies are projected to collide several billion years from now. At the same time, the nature of dark energy remains one of the biggest unanswered questions in cosmology. While observations indicate that the universe's expansion is accelerating, scientists still do not know what is causing that acceleration. Future observations may therefore alter current predictions about the cosmos's ultimate fate. Tye emphasized that additional evidence will be needed before firm conclusions can be drawn. DESI continues to collect data, while upcoming observations from missions and observatories including Euclid, SPHEREx and the Vera C. Rubin Observatory are expected to provide more precise measurements of dark energy. "People have said before that if the cosmological constant is negative, then the universe will collapse eventually. That's not new," Tye said. "However, here the model tells you when the universe collapses and how it collapses." For now, the study presents one possible future for the cosmos rather than a settled prediction. Whether the universe ultimately ends in a Big Crunch, expands forever, or follows another path entirely remains an open question that future observations will help answer. Source: Cornell University, The Conversation This article was generated with some help from AI and reviewed by an editor. Under Section 107 of the Copyright Act 1976, this material is used for the purpose of news reporting. Fair use is a use permitted by copyright statute that might otherwise be infringing.
  • Recent Achievements

    • First Post
      AndreaB earned a badge
      First Post
    • Week One Done
      Huge Trailer earned a badge
      Week One Done
    • Week One Done
      Classifyskilleducation earned a badge
      Week One Done
    • One Month Later
      eurospharma62 earned a badge
      One Month Later
    • Week One Done
      With What earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      570
    2. 2
      +Edouard
      175
    3. 3
      PsYcHoKiLLa
      73
    4. 4
      Michael Scrip
      68
    5. 5
      neufuse
      64
  • Tell a friend

    Love Neowin? Tell a friend!