• 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

    • Flameshot 14.0 Final by Razvan Serea Flameshot is a free and open-source, cross-platform tool to take screenshots with many built-in features to save you time. Using Flameshot is as simple as launching, dragging the selection box to cover the area you want to capture, making annotations as needed in on-screen and saving the shot to your computer, all with a very simple and straightforward interface. Flameshot allows users to simply upload their screenshots directly to the cloud in order to easily share it with others. You can upload your image directly to Imgur with a single click and share the URL with others. In-app screenshot editing - You can choose to add an arrow mark, highlight text, blur a section (blur or pixelate an area), add a text, draw something, add a rectangular/circular shaped border, add an incrementing counter number, and add a solid color box with Flameshot's built-in editing tools. Command-line interface (CLI) - Flameshot has several commands you can use in the terminal without launching the GUI via a command line interface. The command line interface lets you script Flameshot and use it as the subject of key binds. Flameshot 14.0 release notes: This release brings major improvements to multi-monitor support, fractional scaling support, new capture workflows, and a long list of bug fixes across all platforms. Changelog: New Multi-Monitor Capture Workflow New monitor selection screen before capture for better multi-monitor and mixed-scaling support. Option to auto-capture the monitor under the cursor (X11 & Windows). Tray menu can directly select a monitor. Linux Improvements XDG Desktop Portal is now the primary screenshot method. Added legacy X11 fallback option for minimal window managers. New D-Bus capture API for scripting and automation. Windows Enhancements Global screenshot hotkeys now supported (not limited to Print Screen). New portable mode stores settings next to the executable. Clipboard now always uses PNG format for better compatibility. CLI & Platform Updates Redesigned flameshot screen command with per-monitor capture support. Added native Nix Flake support. More compact launcher UI and improved update notifications. Major Fixes Multiple Wayland stability fixes, including KDE Plasma crash fixes. Clipboard compatibility improvements for GNOME, Wayland, X11, Windows, and macOS. Fixed D-Bus hangs, capture crashes, and HiDPI region issues. Other Changes Dropped Ubuntu 20.04 (Focal) support. Updated translations and build infrastructure. Intel macOS builds are no longer provided. [full release notes] Download: Flameshot 14.0 | 18.1 MB (Open Source) Download: Flameshot Portable | 53.0 MB Links: Flameshot Home Page | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • Helium Browser 0.13.4.1 by Razvan Serea Helium is a private, fast, and honest Chromium-based web browser — built for people, with love. It offers the best privacy by default, unbiased ad-blocking, and a clean experience free from bloat and noise. Proudly based on Ungoogled-Chromium, Helium removes Google’s clutter while keeping a fast, efficient development pipeline. With thoughtful touches like native !bangs and split view, Helium is a people-first, fully open-source browser that puts control back in your hands. Privacy, security, and control come first. Ads, trackers, and third-party cookies are blocked automatically, HTTPS is enforced everywhere, and all Chromium extensions work seamlessly — while Google can’t track your activity. Helium’s 13,000+ offline-ready !bangs let you jump straight to sites or AI tools like ChatGPT instantly. Open-source, people-first, and unbiased, Helium delivers a browsing experience that’s fast, secure, and free from noise, ads, and compromises. Helium Browser key features: Performance Fast, efficient, and lightweight — built on Chromium’s optimized engine. Energy-saving and consistent — stays fast over time without slowing down. No bloat — stripped of unnecessary components for maximum speed. Minimalist interface — compact, clean, and distraction-free. Customizable toolbar — hide elements you don’t need. Smooth and stable — no flicker, lag, or animation glitches. Comfort-focused experience — intuitive and unobtrusive. Privacy & Security Best privacy by default — blocks ads, trackers, phishing, and third-party cookies. Unbiased ad-blocking — powered by community filters and uBlock Origin. No telemetry or analytics — zero background web requests on first launch. Strict HTTPS enforcement — warns for insecure sites. Passkeys supported — modern authentication made simple. No built-in password manager or cloud sync — your data stays yours. Extension Compatibility Full Chromium extension support — including MV2 extensions. Anonymized Chrome Web Store requests — Google can’t track extension installs. Extended MV2 support — maintained for as long as possible. Smart Features Native !bangs — browse faster using 13,000+ offline-ready shortcuts. AI integration — use !chatgpt and others directly from the address bar. Offline functionality — bangs work without an Internet connection. Philosophy People-first design — open source, transparent, and community-driven. No ads, no noise, no bias — privacy and honesty over profit. Helium Browser 0.13.4.1 changelog: 0a4f1149 revision: bump to 4 (#1969) 4848de1f helium/core: enable the chromium screenshot feature (#1968) e0dec3f5 onboarding: integrate strings to i18n system (#1948) 417fa5bc i18n: fix newline parsing for onboarding 7a339b39 i18n: add foraged translations for onboarding 4f090cff i18n/generate: add handling for onboarding strings bfe48d58 i18n_apply: manually override parent grd logic for onboarding strings ab214e3c onboarding: bump in deps, wire up grdp afa6a059 helium/core: disable pdf infobar feature (#1965) eba585e7 helium/ui/vertical: fix new tab button alignment and icon size (#1964) 6ecfc9e0 helium/ui/tabs: fix horizontal tab hover background color (#1963) 3db87dc0 helium/ui/tabs: fix new tab button hover/press colors (#1962) 6bbdcc3e helium/ui: improve tab group UI in all layouts (#1961) 53deb314 helium/ui/tabs: enable tab group hover cards e93aece7 helium/ui/vertical: fix tab group appearance, prevent line overlap 629f5495 helium/ui/tabs: restore solid group header colors, enable new colors 961c962e helium/ui/tabs: move horiz tab group underline to bottom, make it thick c96deab6 merge: update to chromium 149.0.7827.155 (#1959) 36db56b4 i18n: update source.gen.json 5ce006ae patches: refresh for chromium 149.0.7827.155 b4c1ea62 merge: update ungoogled-chromium to 149.0.7827.155 4e5e8671 Update to Chromium 149.0.7827.155 08a3e7da helium/ui/layout: disable mute on collapsed vertical tabs (#1778) a0a5bbaf helium/core: simplify context menu and prevent huge widths (#1951) c4732aac devutils/i18n: add forage command (#1944) 11d16986 devutils/i18n: add an option to translate using local CLI tools (#1942) d820c3a2 i18n/prompt: tighten translation rules to prevent common errors (#1940) cf827007 Update to Chromium 149.0.7827.114 6e3d5164 Update to Chromium 149.0.7827.102 Download: Helium 64-bit | Portable 64-bit |~100.0 MB (Open Source) Download: Helium ARM64 | Portable ARM64 Links: Helium Home Page | macOS | Linux | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • Glow 26.10 by Razvan Serea Glow provides detailed reporting on every hardware component in your computer, saving you valuable time typically spent searching for CPU, motherboard, RAM, graphics card, and other stats. With Glow, all the information is conveniently presented in one clean interface, allowing you to easily access and review the comprehensive hardware details of your system. Glow provides detailed information on various system aspects, including OS, motherboard, processor, memory, graphics card, storage, network, battery, drivers, and services. The well-organized format ensures easy access to the required information. You can export all the gathered data to a plain text file, facilitating sharing with others for troubleshooting purposes. No installation needed. Just decompress the archive, launch the executable, and access computer-related information. Glow runs on Windows 11 and Windows 10 64-bit versions. Glow 26.10 changelog: New Features The bootstrapping algorithm has been completely redesigned. The software can now launch directly without requiring TS Preloader. As part of this change, the startup splash screen displayed during initialization has been removed. In addition, spikes in CPU usage have been eliminated, resulting in a more stable architecture with significantly lower memory consumption. The Microsoft Office detection infrastructure within the Operating System section has been enhanced. Additional detection support has been added for Office C2R (Click-to-Run) installations. Furthermore, the license status evaluation system has been improved, and the priority order has been revised as follows: Licensed > Grace Period > Other (NOTIFICATIONS, EVALUATION, etc.). Glow now includes preliminary support for Wi-Fi 8 technology, allowing more detailed information to be displayed for Wi-Fi 8-compatible network adapters. Glow now provides full support for Bluetooth 6.2. Adapters supporting Bluetooth 6.2 can be analyzed in greater detail and with improved accuracy. The disk distribution view in the Disk section has been modernized, replacing the traditional table layout with a new 2×2 card-based design. The TS Custom Controls module has been updated to v26.7. Thanks to the new custom controls, all Türkaysoft applications now offer a more modern and consistent user interface aligned with Windows 11 design standards. Bug Fixes Potential line-ending handling issues in the Office detection code within the Operating System section have been resolved. Additionally, the output format has been standardized to UTF-8 to prevent character encoding issues and ensure consistent data processing. Several stability and file management issues within the Debugging infrastructure have been addressed. Problems that prevented new log files from being created after Debugging was disabled, as well as issues causing debug records to be lost, have been fixed. File deletion and reaccess issues that occurred after file locks were released have also been resolved. In addition, a bug that caused newly recreated log files to remain locked after deletion has been eliminated. Unnecessary blank lines within debug logs and the extra empty line that could appear at the end of log files have also been corrected. A shortcut key conflict caused by assigning identical hotkeys to both the DNS Test Tool and the Donation page has been fixed. The DNS Test Tool can now be accessed using CTRL + Shift + D, while the Donation page is available via CTRL + Alt + D. Changes The service responsible for providing the Public IP Address and Internet Service Provider information in the Network section has been updated to use the ipinfo.io infrastructure. This change improves the accuracy and consistency of the displayed data. (No external requests are made while Hiding Mode is enabled.) Some terms in the Dutch and Korean language files have been updated to make them clearer and more user-friendly. [TS Updater] Before the update process begins, users are now prompted to choose whether they would like to view the release notes. Note: Always unzip the program before using it. Otherwise you may get an error. Download: Glow 26.10 | 1.8 MB (Open Source) Links: Glow Homepage | Screenshot | Github Get alerted to all of our Software updates on Twitter at @NeowinSoftware
  • Recent Achievements

    • Reacting Well
      BizSAR earned a badge
      Reacting Well
    • 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
  • Popular Contributors

    1. 1
      +primortal
      582
    2. 2
      +Edouard
      183
    3. 3
      PsYcHoKiLLa
      75
    4. 4
      Michael Scrip
      73
    5. 5
      neufuse
      64
  • Tell a friend

    Love Neowin? Tell a friend!