{"id":6646,"date":"2024-11-02T00:01:00","date_gmt":"2024-11-02T07:01:00","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6646"},"modified":"2024-10-26T10:26:37","modified_gmt":"2024-10-26T17:26:37","slug":"testing-for-the-random-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6646","title":{"rendered":"Testing For the <em>random()<\/em> Function"},"content":{"rendered":"<p>Silly me. I once assumed that just because my compiler offered the <em>random()<\/em> function &mdash; a superior version of the C library standard <em>rand()<\/em> function &mdash; that every compiler fatured this function. Boy, was I wrong!<br \/>\n<!--more--><br \/>\nThe <em>random()<\/em> function improves upon the randomness of <em>rand()<\/em> using technical mumbo jumbo that I don&#8217;t want to understand. It also features a companion, <em>srandom()<\/em> function to seed its randomizer. All I know is that these functions are better than <em>rand()<\/em> and <em>srand()<\/em>. But I also learned is that not every compiler offers these POSIX\/BSD functions.<\/p>\n<p>To write the best code, you should check for compatibility before implementing a POSIX or BSD function like <em>random()<\/em>. The test parameters are listed in the function&#8217;s <em>man<\/em> page documentation:<\/p>\n<p><code>CONFORMING TO&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;POSIX.1-2001, POSIX.1-2008, 4.3BSD.<\/code><\/p>\n<p>The POSIX defined constant to test is named <code>_POSIX_C_SOURCE<\/code>. This value must be greater than or equal to 200112L (<em>long int<\/em>) to ensure that the relevant function is available as documented.<\/p>\n<p>The following code tests the POSIX version, confirming whether the <em>random()<\/em> function is available.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2024_11_02-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2024_11_02-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\n#ifndef _POSIX_C_SOURCE\r\n#define _POSIX_C_SOURCE 0\r\n#endif\r\n\r\nint main()\r\n{\r\n    <span class=\"comments\">\/* test for presence of random() function *\/<\/span>\r\n\r\n    if( _POSIX_C_SOURCE &gt;= 200112L )\r\n        puts(\"The random() function is available\");\r\n    else\r\n        puts(\"The random() function is not available\");\r\n\r\n    return 0;\r\n}<\/pre>\n<p>Before the <em>main()<\/em> function, the precompiler tests for the presence of the <code>_POSIX_C_SOURCE<\/code> defined constant. If the constant is undefined, the code defines it. This test ensures that the code compiles, otherwise an error occurs should the defined constant be undefined.<\/p>\n<p>Within the <em>main()<\/em> function, the value of <code>_POSIX_C_SOURCE<\/code> is compared with 200112L. When true (the value is greater than or equal to), the output shows that the <em>random()<\/em> function is available.<\/p>\n<p>Here&#8217;s a sample run:<\/p>\n<p><code>The random() function is available<\/code><\/p>\n<p>If I compile the code with the <code>-ansi<\/code> switch, setting it to conform with the original ANSI C standard, I see this result:<\/p>\n<p><code>The random() function is not available<\/code><\/p>\n<p>This is the output a user sees when the compiler doesn&#8217;t use the POSIX C extensions.<\/p>\n<p>The following code is more practical, showing how to implement the test:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2024_11_02-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2024_11_02-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;time.h&gt;\r\n\r\nint main()\r\n{\r\n    int x;\r\n\r\n#ifdef _POSIX_C_SOURCE\r\n    if( _POSIX_C_SOURCE &gt;= 200112L )\r\n    {\r\n        srandom( (unsigned)time(NULL) );\r\n        puts(\"The random() function:\");\r\n        for( x=0; x&lt;10; x++ )\r\n            printf(\"%ld\\n\",random());\r\n    }\r\n    else\r\n    {\r\n        srand( (unsigned)time(NULL) );\r\n        puts(\"The rand() function:\");\r\n        for( x=0; x&lt;10; x++ )\r\n            printf(\"%d\\n\",rand());\r\n    }\r\n#else\r\n    srand( (unsigned)time(NULL) );\r\n    puts(\"The rand() function:\");\r\n    for( x=0; x&lt;10; x++ )\r\n        printf(\"%d\\n\",rand());\r\n#endif\r\n\r\n    return 0;\r\n}<\/pre>\n<p>With this example, the precompiler directives are checked inside the code. When the <code>_POSIX_C_SOURCE<\/code> constant is defined (<code>#ifdef<\/code>), a <em>if<\/em> test ensures that the version is compatible with the <em>random()<\/em> function:<\/p>\n<p><code>if( _POSIX_C_SOURCE &gt;= 200112L )<\/code><\/p>\n<p>Otherwise, <em>the<\/em> else part of the code uses the <em>rand()<\/em> function.<\/p>\n<p>The <code>#else<\/code> directive handles the case when the <code>_POSIX_C_SOURCE<\/code> constant is undefined. This part of the code is compiled using only the <em>rand()<\/em> function.<\/p>\n<p>An <code>#endif<\/code> directive ends the <code>#ifdef<\/code> &#8211; <code>#else<\/code> construction.<\/p>\n<p>Here is the output:<\/p>\n<p><code>The random() function:<br \/>\n1650599212<br \/>\n420354732<br \/>\n1514728248<br \/>\n139032251<br \/>\n1888432268<br \/>\n1534300142<br \/>\n157468978<br \/>\n1753183110<br \/>\n1160242387<br \/>\n22997577<\/code><\/p>\n<p>When the <code>-ansi<\/code> switch is used to compile the code, here is the output:<\/p>\n<p><code>The rand() function:<br \/>\n1512047070<br \/>\n1354075150<br \/>\n158955988<br \/>\n1182828959<br \/>\n332400900<br \/>\n1817095792<br \/>\n1455458813<br \/>\n418963527<br \/>\n1268248241<br \/>\n1994796880<\/code><\/p>\n<p>This code is built to handle three situations: When the POSIX standard is compatible with <em>random()<\/em>, when it&#8217;s not, and when the POSIX standard is undefined. Thanks to the precompiler directives, two different programs are generated depending on the presence of the <code>_POSIX_C_SOURCE<\/code> constant. The program can build on any platform and do its job, even when the <em>random()<\/em> function is unavailable.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The <em>random()<\/em> function is better than <em>rand()<\/em>, though it may not be available with all C compilers. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6646\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-6646","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6646","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6646"}],"version-history":[{"count":6,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6646\/revisions"}],"predecessor-version":[{"id":6662,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6646\/revisions\/6662"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6646"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6646"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6646"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}