Sum of odd numbers from 1 - 100 using RECURSION in C - c

Trying to figure out where I am going wrong in this code, I realize I keep getting 1 because that's what am I passing in the function but how else can I do this?
#include <stdio.h>
#include <stdlib.h>
int totalOdd();
int main(){
printf("%d\n",totalOdd(1));
}
int totalOdd(int n){
int odd = n;
if(odd >= 100){
return 0;
}
else{
totalOdd(odd+2);
}
return odd;
}

try this one
one :
#include <stdio.h>
#include <stdlib.h>
int totalOdd(int);
int main(){
printf("%d\n",totalOdd(1));
}
int totalOdd(int n)
{
int odd = n;
if(odd > 100){
return 0;
}
else{
return (n+totalOdd(odd+2));
}
}
in your code , addition was missing

#include <stdio.h>
#include <stdlib.h>
int totalOdd();
int main(){
printf("%d\n",totalOdd(1));
}
int totalOdd(int odd){
if(odd >= 100)
return 0;
return (odd + totalOdd(odd + 2));
}

Not a complete answer, because this sounds like homework, but here’s an example of how to write a very similar function, first recursively, and then a more efficient tail-recursive solution.
#include <stdio.h>
#include <stdlib.h>
unsigned long factorial1(const unsigned long n)
{
/* The naive implementation. */
if ( n <= 1U )
return 1; // 0! is the nullary product, 1.
else
return n*factorial1(n-1);
/* Notice that there is one more operation after the call to
* factorial1() above: a multiplication. Most compilers need to keep
* all the intermediate results on the stack and do all the multiplic-
* ations after factorial1(1) returns.
*/
}
static unsigned long factorial_helper( const unsigned long n,
const unsigned long accumulator )
{
/* Most compilers should be able to optimize this tail-recursive version
* into faster code.
*/
if ( n <= 1U )
return accumulator;
else
return factorial_helper( n-1, n*accumulator );
/* Notice that the return value is simply another call to the same function.
* This pattern is called tail-recursion, and is as efficient as iterative
* code (like a for loop).
*/
}
unsigned long factorial2(const unsigned long n)
{
return factorial_helper( n, 1U );
}
int main(void)
{
printf( "%lu = %lu\n", factorial1(10), factorial2(10) );
return EXIT_SUCCESS;
}
Examining the output of both gcc -O -S and clang -O -S on the above code, I see that in practice, clang 3.8.1 can compile both versions to the same optimized loop, and gcc 6.2.0 does not optimize for tail recursion on either, but there are compilers where it would make a difference.
For future reference, you wouldn’t solve this specific problem this way in the real world, but you will use this pattern for other things, especially in functional programming. There is a closed-form solution to the sum of odd numbers in a range. You can use that to get the answer in constant time. You want to look for those whenever possible! Hint: it is the sum, from i = 0 to 100, of 2 i + 1. Do you remember a closed-form formula for the sum of i from 0 to N? 0, 1, 3, 6, 10, 15, ...? The proof is often taught as an example of a proof by induction. And what happens to a sum from 0 to N when you multiply and add by constants?
As for my example, when I have had to compute a factorial function in a real program, it was for the purpose of computing a probability distribution (specifically, the Poisson distribution) for a simulation, and I needed to calculate the factorial of the same numbers repeatedly. Therefore, what I did was store a list of all the factorials I’d already calculated, and look up any number I saw again in that list. That pattern is called memoization.

Related

Why rand() function in C is generating the same no. again and again? [duplicate]

Is there a function to generate a random int number in C? Or will I have to use a third party library?
Note: Don't use rand() for security. If you need a cryptographically secure number, see this answer instead.
#include <time.h>
#include <stdlib.h>
srand(time(NULL)); // Initialization, should only be called once.
int r = rand(); // Returns a pseudo-random integer between 0 and RAND_MAX.
On Linux, you might prefer to use random and srandom.
The rand() function in <stdlib.h> returns a pseudo-random integer between 0 and RAND_MAX. You can use srand(unsigned int seed) to set a seed.
It's common practice to use the % operator in conjunction with rand() to get a different range (though bear in mind that this throws off the uniformity somewhat). For example:
/* random int between 0 and 19 */
int r = rand() % 20;
If you really care about uniformity you can do something like this:
/* Returns an integer in the range [0, n).
*
* Uses rand(), and so is affected-by/affects the same seed.
*/
int randint(int n) {
if ((n - 1) == RAND_MAX) {
return rand();
} else {
// Supporting larger values for n would requires an even more
// elaborate implementation that combines multiple calls to rand()
assert (n <= RAND_MAX)
// Chop off all of the values that would cause skew...
int end = RAND_MAX / n; // truncate skew
assert (end > 0);
end *= n;
// ... and ignore results from rand() that fall above that limit.
// (Worst case the loop condition should succeed 50% of the time,
// so we can expect to bail out of this loop pretty quickly.)
int r;
while ((r = rand()) >= end);
return r % n;
}
}
If you need secure random characters or integers:
As addressed in how to safely generate random numbers in various programming languages, you'll want to do one of the following:
Use libsodium's randombytes API
Re-implement what you need from libsodium's sysrandom implementation yourself, very carefully
More broadly, use /dev/urandom, not /dev/random. Not OpenSSL (or other userspace PRNGs).
For example:
#include "sodium.h"
int foo()
{
char myString[32];
uint32_t myInt;
if (sodium_init() < 0) {
/* panic! the library couldn't be initialized, it is not safe to use */
return 1;
}
/* myString will be an array of 32 random bytes, not null-terminated */
randombytes_buf(myString, 32);
/* myInt will be a random number between 0 and 9 */
myInt = randombytes_uniform(10);
}
randombytes_uniform() is cryptographically secure and unbiased.
Lets go through this. First we use the srand() function to seed the randomizer. Basically, the computer can generate random numbers based on the number that is fed to srand(). If you gave the same seed value, then the same random numbers would be generated every time.
Therefore, we have to seed the randomizer with a value that is always changing. We do this by feeding it the value of the current time with the time() function.
Now, when we call rand(), a new random number will be produced every time.
#include <stdio.h>
int random_number(int min_num, int max_num);
int main(void)
{
printf("Min : 1 Max : 40 %d\n", random_number(1,40));
printf("Min : 100 Max : 1000 %d\n",random_number(100,1000));
return 0;
}
int random_number(int min_num, int max_num)
{
int result = 0, low_num = 0, hi_num = 0;
if (min_num < max_num)
{
low_num = min_num;
hi_num = max_num + 1; // include max_num in output
} else {
low_num = max_num + 1; // include max_num in output
hi_num = min_num;
}
srand(time(NULL));
result = (rand() % (hi_num - low_num)) + low_num;
return result;
}
If you need better quality pseudo random numbers than what stdlib provides, check out Mersenne Twister. It's faster, too. Sample implementations are plentiful, for example here.
The standard C function is rand(). It's good enough to deal cards for solitaire, but it's awful. Many implementations of rand() cycle through a short list of numbers, and the low bits have shorter cycles. The way that some programs call rand() is awful, and calculating a good seed to pass to srand() is hard.
The best way to generate random numbers in C is to use a third-party library like OpenSSL. For example,
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <openssl/rand.h>
/* Random integer in [0, limit) */
unsigned int random_uint(unsigned int limit) {
union {
unsigned int i;
unsigned char c[sizeof(unsigned int)];
} u;
do {
if (!RAND_bytes(u.c, sizeof(u.c))) {
fprintf(stderr, "Can't get random bytes!\n");
exit(1);
}
} while (u.i < (-limit % limit)); /* u.i < (2**size % limit) */
return u.i % limit;
}
/* Random double in [0.0, 1.0) */
double random_double() {
union {
uint64_t i;
unsigned char c[sizeof(uint64_t)];
} u;
if (!RAND_bytes(u.c, sizeof(u.c))) {
fprintf(stderr, "Can't get random bytes!\n");
exit(1);
}
/* 53 bits / 2**53 */
return (u.i >> 11) * (1.0/9007199254740992.0);
}
int main() {
printf("Dice: %d\n", (int)(random_uint(6) + 1));
printf("Double: %f\n", random_double());
return 0;
}
Why so much code? Other languages like Java and Ruby have functions for random integers or floats. OpenSSL only gives random bytes, so I try to mimic how Java or Ruby would transform them into integers or floats.
For integers, we want to avoid modulo bias. Suppose that we got some random 4 digit integers from rand() % 10000, but rand() can only return 0 to 32767 (as it does in Microsoft Windows). Each number from 0 to 2767 would appear more often than each number from 2768 to 9999. To remove the bias, we can retry rand() while the value is below 2768, because the 30000 values from 2768 to 32767 map uniformly onto the 10000 values from 0 to 9999.
For floats, we want 53 random bits, because a double holds 53 bits of precision (assuming it's an IEEE double). If we use more than 53 bits, we get rounding bias. Some programmers write code like rand() / (double)RAND_MAX, but rand() might return only 31 bits, or only 15 bits in Windows.
OpenSSL's RAND_bytes() seeds itself, perhaps by reading /dev/urandom in Linux. If we need many random numbers, it would be too slow to read them all from /dev/urandom, because they must be copied from the kernel. It is faster to allow OpenSSL to generate more random numbers from a seed.
More about random numbers:
Perl's Perl_seed() is an example of how to calculate a seed in C for srand(). It mixes bits from the current time, the process ID, and some pointers, if it can't read /dev/urandom.
OpenBSD's arc4random_uniform() explains modulo bias.
Java API for java.util.Random describes algorithms for removing bias from random integers, and packing 53 bits into random floats.
If your system supports the arc4random family of functions I would recommend using those instead the standard rand function.
The arc4random family includes:
uint32_t arc4random(void)
void arc4random_buf(void *buf, size_t bytes)
uint32_t arc4random_uniform(uint32_t limit)
void arc4random_stir(void)
void arc4random_addrandom(unsigned char *dat, int datlen)
arc4random returns a random 32-bit unsigned integer.
arc4random_buf puts random content in it's parameter buf : void *. The amount of content is determined by the bytes : size_t parameter.
arc4random_uniform returns a random 32-bit unsigned integer which follows the rule: 0 <= arc4random_uniform(limit) < limit, where limit is also an unsigned 32-bit integer.
arc4random_stir reads data from /dev/urandom and passes the data to arc4random_addrandom to additionally randomize it's internal random number pool.
arc4random_addrandom is used by arc4random_stir to populate it's internal random number pool according to the data passed to it.
If you do not have these functions, but you are on Unix, then you can use this code:
/* This is C, not C++ */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h> /* exit */
#include <stdio.h> /* printf */
int urandom_fd = -2;
void urandom_init() {
urandom_fd = open("/dev/urandom", O_RDONLY);
if (urandom_fd == -1) {
int errsv = urandom_fd;
printf("Error opening [/dev/urandom]: %i\n", errsv);
exit(1);
}
}
unsigned long urandom() {
unsigned long buf_impl;
unsigned long *buf = &buf_impl;
if (urandom_fd == -2) {
urandom_init();
}
/* Read sizeof(long) bytes (usually 8) into *buf, which points to buf_impl */
read(urandom_fd, buf, sizeof(long));
return buf_impl;
}
The urandom_init function opens the /dev/urandom device, and puts the file descriptor in urandom_fd.
The urandom function is basically the same as a call to rand, except more secure, and it returns a long (easily changeable).
However, /dev/urandom can be a little slow, so it is recommended that you use it as a seed for a different random number generator.
If your system does not have a /dev/urandom, but does have a /dev/random or similar file, then you can simply change the path passed to open in urandom_init. The calls and APIs used in urandom_init and urandom are (I believe) POSIX-compliant, and as such, should work on most, if not all POSIX compliant systems.
Notes: A read from /dev/urandom will NOT block if there is insufficient entropy available, so values generated under such circumstances may be cryptographically insecure. If you are worried about that, then use /dev/random, which will always block if there is insufficient entropy.
If you are on another system(i.e. Windows), then use rand or some internal Windows specific platform-dependent non-portable API.
Wrapper function for urandom, rand, or arc4random calls:
#define RAND_IMPL /* urandom(see large code block) | rand | arc4random */
int myRandom(int bottom, int top){
return (RAND_IMPL() % (top - bottom)) + bottom;
}
STL doesn't exist for C. You have to call rand, or better yet, random. These are declared in the standard library header stdlib.h. rand is POSIX, random is a BSD spec function.
The difference between rand and random is that random returns a much more usable 32-bit random number, and rand typically returns a 16-bit number. The BSD manpages show that the lower bits of rand are cyclic and predictable, so rand is potentially useless for small numbers.
Have a look at ISAAC (Indirection, Shift, Accumulate, Add, and Count). Its uniformly distributed and has an average cycle length of 2^8295.
This is a good way to get a random number between two numbers of your choice.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define randnum(min, max) \
((rand() % (int)(((max) + 1) - (min))) + (min))
int main()
{
srand(time(NULL));
printf("%d\n", randnum(1, 70));
}
Output the first time: 39
Output the second time: 61
Output the third time: 65
You can change the values after randnum to whatever numbers you choose, and it will generate a random number for you between those two numbers.
I had a serious issue with pseudo random number generator in my recent application: I repeatedly called my C program via a Python script and I was using as seed the following code:
srand(time(NULL))
However, since:
rand will generate the same pseudo random sequence give the same seed in srand (see man srand);
As already stated, time function changes only second from second: if your application is run multiple times within the same second, time will return the same value each time.
My program generated the same sequence of numbers.
You can do 3 things to solve this problem:
mix time output with some other information changing on runs (in my application, the output name):
srand(time(NULL) | getHashOfString(outputName))
I used djb2 as my hash function.
Increase time resolution. On my platform, clock_gettime was available, so I use it:
#include<time.h>
struct timespec nanos;
clock_gettime(CLOCK_MONOTONIC, &nanos)
srand(nanos.tv_nsec);
Use both methods together:
#include<time.h>
struct timespec nanos;
clock_gettime(CLOCK_MONOTONIC, &nanos)
srand(nanos.tv_nsec | getHashOfString(outputName));
Option 3 ensures you (as far as I know) the best seed randomness, but it may create a difference only on very fast application.
In my opinion option 2 is a safe bet.
Well, STL is C++, not C, so I don't know what you want. If you want C, however, there is the rand() and srand() functions:
int rand(void);
void srand(unsigned seed);
These are both part of ANSI C. There is also the random() function:
long random(void);
But as far as I can tell, random() is not standard ANSI C. A third-party library may not be a bad idea, but it all depends on how random of a number you really need to generate.
You want to use rand(). Note (VERY IMPORTANT): make sure to set the seed for the rand function. If you do not, your random numbers are not truly random. This is very, very, very important. Thankfully, you can usually use some combination of the system ticks timer and the date to get a good seed.
FWIW, the answer is that yes, there is a stdlib.h function called rand; this function is tuned primarily for speed and distribution, not for unpredictability. Almost all built-in random functions for various languages and frameworks use this function by default. There are also "cryptographic" random number generators that are much less predictable, but run much slower. These should be used in any sort of security-related application.
This is hopefully a bit more random than just using srand(time(NULL)).
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
srand((unsigned int)**main + (unsigned int)&argc + (unsigned int)time(NULL));
srand(rand());
for (int i = 0; i < 10; i++)
printf("%d\n", rand());
}
C Program to generate random number between 9 and 50
#include <time.h>
#include <stdlib.h>
int main()
{
srand(time(NULL));
int lowerLimit = 10, upperLimit = 50;
int r = lowerLimit + rand() % (upperLimit - lowerLimit);
printf("%d", r);
}
In general we can generate a random number between lowerLimit and upperLimit-1
i.e lowerLimit is inclusive or say r ∈ [ lowerLimit, upperLimit )
On modern x86_64 CPUs you can use the hardware random number generator via _rdrand64_step()
Example code:
#include <immintrin.h>
uint64_t randVal;
if(!_rdrand64_step(&randVal)) {
// Report an error here: random number generation has failed!
}
// If no error occured, randVal contains a random 64-bit number
rand() is the most convenient way to generate random numbers.
You may also catch random number from any online service like random.org.
#include <stdio.h>
#include <stdlib.h>
void main()
{
int visited[100];
int randValue, a, b, vindex = 0;
randValue = (rand() % 100) + 1;
while (vindex < 100) {
for (b = 0; b < vindex; b++) {
if (visited[b] == randValue) {
randValue = (rand() % 100) + 1;
b = 0;
}
}
visited[vindex++] = randValue;
}
for (a = 0; a < 100; a++)
printf("%d ", visited[a]);
}
Despite all the people suggestion rand() here, you don't want to use rand() unless you have to! The random numbers that rand() produces are often very bad. To quote from the Linux man page:
The versions of rand() and srand() in the Linux C Library use the same random number generator as random(3) and srandom(3), so the lower-order bits should be as random as the higher-order bits. However, on older rand() implementations, and on current implementations on different systems, the lower-order bits are much less random than the higher-order bits. Do not use this function in applications intended to be portable when good randomness is needed. (Use random(3) instead.)
Regarding portability, random() is also defined by the POSIX standard for quite some time now. rand() is older, it appeared already in the first POSIX.1 spec (IEEE Std 1003.1-1988), whereas random() first appeared in POSIX.1-2001 (IEEE Std 1003.1-2001), yet the current POSIX standard is already POSIX.1-2008 (IEEE Std 1003.1-2008), which received an update just a year ago (IEEE Std 1003.1-2008, 2016 Edition). So I would consider random() to be very portable.
POSIX.1-2001 also introduced the lrand48() and mrand48() functions, see here:
This family of functions shall generate pseudo-random numbers using a linear congruential algorithm and 48-bit integer arithmetic.
And a pretty good pseudo random source is the arc4random() function that is available on many systems. Not part of any official standard, appeared in BSD around 1997 but you can find it on systems like Linux and macOS/iOS.
#include <stdio.h>
#include <dos.h>
int random(int range);
int main(void)
{
printf("%d", random(10));
return 0;
}
int random(int range)
{
struct time t;
int r;
gettime(&t);
r = t.ti_sec % range;
return r;
}
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//generate number in range [min,max)
int random(int min, int max){
int number = min + rand() % (max - min);
return number;
}
//Driver code
int main(){
srand(time(NULL));
for(int i = 1; i <= 10; i++){
printf("%d\t", random(10, 100));
}
return 0;
}
For Linux C applications:
This is my reworked code from an answer above that follows my C code practices and returns a random buffer of any size (with proper return codes, etc.). Make sure to call urandom_open() once at the beginning of your program.
int gUrandomFd = -1;
int urandom_open(void)
{
if (gUrandomFd == -1) {
gUrandomFd = open("/dev/urandom", O_RDONLY);
}
if (gUrandomFd == -1) {
fprintf(stderr, "Error opening /dev/urandom: errno [%d], strerrer [%s]\n",
errno, strerror(errno));
return -1;
} else {
return 0;
}
}
void urandom_close(void)
{
close(gUrandomFd);
gUrandomFd = -1;
}
//
// This link essentially validates the merits of /dev/urandom:
// http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/
//
int getRandomBuffer(uint8_t *buf, int size)
{
int ret = 0; // Return value
if (gUrandomFd == -1) {
fprintf(stderr, "Urandom (/dev/urandom) file not open\n");
return -1;
}
ret = read(gUrandomFd, buf, size);
if (ret != size) {
fprintf(stderr, "Only read [%d] bytes, expected [%d]\n",
ret, size);
return -1;
} else {
return 0;
}
}
Here is my approach (a wrapper around rand()):
I also scale to allow a case where min is INT_MIN and max is INT_MAX, which is normally not possible with rand() alone since it returns values from 0 to RAND_MAX, inclusive (1/2 that range).
Use it like this:
const int MIN = 1;
const int MAX = 1024;
// Get a pseudo-random number between MIN and MAX, **inclusive**.
// Seeding of the pseudo-random number generator automatically occurs
// the very first time you call it.
int random_num = utils_rand(MIN, MAX);
Definitions and doxygen descriptions:
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
/// \brief Use linear interpolation to rescale, or "map" value `val` from range
/// `in_min` to `in_max`, inclusive, to range `out_min` to `out_max`, inclusive.
/// \details Similar to Arduino's ingenious `map()` function:
/// https://www.arduino.cc/reference/en/language/functions/math/map/
///
/// TODO(gabriel): turn this into a gcc statement expression instead to prevent the potential for
/// the "double evaluation" bug. See `MIN()` and `MAX()` above.
#define UTILS_MAP(val, in_min, in_max, out_min, out_max) \
(((val) - (in_min)) * ((out_max) - (out_min)) / ((in_max) - (in_min)) + (out_min))
/// \brief Obtain a pseudo-random integer value between `min` and `max`, **inclusive**.
/// \details 1. If `(max - min + 1) > RAND_MAX`, then the range of values returned will be
/// **scaled** to the range `max - min + 1`, and centered over the center of the
/// range at `(min + max)/2`. Scaling the numbers means that in the case of scaling,
/// not all numbers can even be reached. However, you will still be assured to have
/// a random distribution of numbers across the full range.
/// 2. Also, the first time per program run that you call this function, it will
/// automatically seed the pseudo-random number generator with your system's
/// current time in seconds.
/// \param[in] min The minimum pseudo-random number you'd like, inclusive. Can be positive
/// OR negative.
/// \param[in] max The maximum pseudo-random number you'd like, inclusive. Can be positive
/// OR negative.
/// \return A pseudo-random integer value between `min` and `max`, **inclusive**.
int utils_rand(int min, int max)
{
static bool first_run = true;
if (first_run)
{
// seed the pseudo-random number generator with the seconds time the very first run
time_t time_now_sec = time(NULL);
srand(time_now_sec);
first_run = false;
}
int range = max - min + 1;
int random_num = rand(); // random num from 0 to RAND_MAX, inclusive
if (range > RAND_MAX)
{
static_assert(
sizeof(long int) > sizeof(int),
"This must be true or else the below mapping/scaling may have undefined overflow "
"and not work properly. In such a case, try casting to `long long int` instead of "
"just `long int`, and update this static_assert accordingly.");
random_num = UTILS_MAP((long int)random_num, (long int)0, (long int)RAND_MAX, (long int)min,
(long int)max);
return random_num;
}
// This is presumably a faster approach than the map/scaling function above, so do this faster
// approach below whenever you don't **have** to do the more-complicated approach above.
random_num %= range;
random_num += min;
return random_num;
}
See also:
[I discovered this Q&A after writing my answer above, but it is obviously very relevant, and they do the same thing I do for the non-scaling range case] How do I get a specific range of numbers from rand()?
[I NEED TO STUDY AND READ THIS ANSWER MORE STILL--seems to have some good points about retaining good randomness by not using modulus alone] How do I get a specific range of numbers from rand()?
http://c-faq.com/lib/randrange.html
If you need, say, 128 secure random bits, the RFC 1750 compliant solution is to read hardware source that is known to generate useable bits of entropy (such as a spinning disk). Better yet, good implementations should combine multiple sources using a mixing function, and finally de-skew the distribution of their output, by re-mapping or deleting outputs.
If you need more bits than that, the compliant thing to do is start with sequence of 128 secure random bits and stretch it to a desired length, map it to human readable text, etc.
If you want to generate a secure random number in C I would follow the source code here:
https://wiki.sei.cmu.edu/confluence/display/c/MSC30-C.+Do+not+use+the+rand%28%29+function+for+generating+pseudorandom+numbers
Note that for Windows BCryptGenRandom is used, not CryptGenRandom which has become unsecure within the past two decades. You can confirm for yourself that BCryptGenRandom is compliant with RFC 1750.
For POSIX-compliant operating systems, e.g. Ubuntu (a flavor of Linux), you can simply read from /dev/urandom or /dev/random, which is a file-like interface to a device that generates bits of entropy by combining multiple sources in an RFC 1750 compliant fashion. You can read a desired number of bytes from these "files" with read or fread just like you would any other file, but note that reads from /dev/random will block until a enough new bits of entropy are available, whereas /dev/urandom will not, which can be a security issue. You can get around that by checking the size of the available entropy pool, either my reading from entropy_avail, or by using ioctl.
The glibc-specific function (that should be found in most of Linux environments) related to this is random(), or you may be interested with its thread-safe version random_r(). You have to initialize the struct random_data with initstate_r() prior to passing it to random_r().
Here is quick code sample :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
void xxx (void) {
unsigned int seed = (unsigned int) time(NULL);
char rnd_state[17] = {0};
struct random_data rnd_st_buf = {0};
initstate_r(seed, &rnd_state[0], 17, &rnd_st_buf);
for(size_t idx = 0; idx < 8; idx++) {
int32_t rnd_int = 0;
char rnd_seq_str[6] = {0};
random_r(&rnd_st_buf, &rnd_int);
memcpy((char *)&rnd_seq_str[0], (char *)&rnd_int, 4);
printf("random number : 0x%08x, \n", rnd_int);
}
}
You can generate random chars, then view them as int :
#include <stdlib.h>
#include <stdio.h>
typedef double rand_type; // change double to int
rand_type my_rand() {
char buff[sizeof(rand_type)];
for (size_t i = 0 ; i < sizeof(rand_type) ; ++i)
buff[i] = (char) rand();
return *(rand_type *) buff;
}
int main() {
int i ; // srand as you want
for (i = 0 ; i < 10 ; ++i)
printf("%g\n", my_rand()); // change %g to %d
return 0 ;
}
You can also use mathgl library #include <mgl2/mgl_cf.h> (though first you need to install it, I own installed through MSYS2) with function mgl_rnd(). It also have kinds of distribution like uniform, guassian and more. It's ez to use. But I dont know about it's characteristic.
Hearing a good explanation of why using rand() to produce uniformly distributed random numbers in a given range is a bad idea, I decided to take a look at how skewed the output actually is. My test case was fair dice throwing. Here's the C code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
int i;
int dice[6];
for (i = 0; i < 6; i++)
dice[i] = 0;
srand(time(NULL));
const int TOTAL = 10000000;
for (i = 0; i < TOTAL; i++)
dice[(rand() % 6)] += 1;
double pers = 0.0, tpers = 0.0;
for (i = 0; i < 6; i++) {
pers = (dice[i] * 100.0) / TOTAL;
printf("\t%1d %5.2f%%\n", dice[i], pers);
tpers += pers;
}
printf("\ttotal: %6.2f%%\n", tpers);
}
and here's its output:
$ gcc -o t3 t3.c
$ ./t3
1666598 16.67%
1668630 16.69%
1667682 16.68%
1666049 16.66%
1665948 16.66%
1665093 16.65%
total: 100.00%
$ ./t3
1667634 16.68%
1665914 16.66%
1665542 16.66%
1667828 16.68%
1663649 16.64%
1669433 16.69%
total: 100.00%
I don't know how uniform you need your random numbers to be, but the above appears uniform enough for most needs.
Edit: it would be a good idea to initialize the PRNG with something better than time(NULL).
My minimalistic solution should work for random numbers in range [min, max). Use srand(time(NULL)) before invoking the function.
int range_rand(int min_num, int max_num) {
if (min_num >= max_num) {
fprintf(stderr, "min_num is greater or equal than max_num!\n");
}
return min_num + (rand() % (max_num - min_num));
}

Integer to Binary Conversion Program Fails for Some Inputs

I wrote code for getting binary form of an integer. It works well for inputs like 1 or 10. However, it is failing for inputs like 256. (It gives 0000000 s output and misses the one).
#include <stdio.h>
#include <math.h>
int number_of_binary_digits_required(int n){
return ceil(log(n))+1;
}
void print_array(int * a, int n){
int i = 0;
for (;i<n;i++){
printf("%d\t", a[i]);
}
}
int main(){
int num = 256;
int binary[100];
int n = number_of_binary_digits_required(num);
int bin_digits = n-1;
while (num){
int temp = num%2;
num = num / 2;
binary[bin_digits] = temp;
//printf("%d\n", bin_digits);
bin_digits--;
}
print_array(binary, n);
//printf("%d", number_of_binary_digits_required(num));
//for(bin_digits = 0;bin_digits < number_of_binary_digits_required(num);bin_digits++)
//printf("%d",binary[bin_digits]);
}
Why is the issue coming and how to resolve it?
Thanks you!
C's log function gives result with a base of e, not 2. This is why some numbers give unexpected result in your program since you calculate using that. There is a function log2 which is what you need i think.
Your use of a logarithmic function to compute the number of digits in conjunction with ceil will suffer due to floating point undershoot.
A more reliable way of calculating the number of binary digits is to divide by two repeatedly until zero is attained.
The first mistake is to use log(n), which calculates log of n base e.
Instead use log2(n)
Hope it helps. :-)

C - Recursive function for minimum gap in array

I'm trying to optimize a function that, given an array of N int, return the minimum difference between an element and the previous one. Obviously the function is just for array with a dimension >=2.
For example, given the array {2,5,1}, function returns -4 .
I tried to write my code, but I think it is really intricate.
#include <stdio.h>
#define N 4
/*Function for the difference, works because in the main I already gives one difference*/
int minimodiff(int *a, int n, int diff) {
if (n==1) {
return diff;
}
if (diff>(*(a+1) - *a))
return minimodiff(a+1, n-1, *(a+1)-*a);
else return minimodiff(a+1, n-1, diff);
}
int main() {
int a[N]= {1,8,4,3};
printf("%d", minimodiff(a+1, N-1, *(a+1)-*a));
}
I wonder if there is a way to avoid to pass the first difference in main, but doing everything in the recursive function.
I can use as header file stdio.h / stdlib.h / string.h / math.h . Thanks a lot for the help, I hope that this can give me a better understanding of the recursive functions.
minimodiff(a+1, N-1, *(a+1)-*a) is a weak approach to use recursion for it uses a recursion depths of N which can easily overwhelm system resources depth limit. In such a case, a simple loop would suffice.
A good recursive approach would halve the problem at each call, finding the minimum of the left half and the right half. It may not run faster, but the maximum depth of recursion would be log2(N).
// n is the number of array elements
int minimodiff2(const int *a, size_t n) {
if (n == 2) {
return a[1] - a[0];
} else if (n <= 1) {
return INT_MAX;
}
int left = minimodiff2(a, n/2 + 1); // +1 to include a[n/2] in both halves
int right = minimodiff2(a + n/2, n - n/2);
return (left < right) ? left : right;
}
int main() {
int a[]= {1,8,4,3};
printf("%d", minimodiff2(a, sizeof a/ sizeof a[0]));
}
When doing a min calculation, recursive or otherwise, it makes the initial condition simpler if you set the min to the highest possible value. If you were using floating point numbers it would be Infinity. Since you're using integers, it's INT_MAX from limits.h which is defined as the highest possible integer. It is guaranteed to be greater than or equal to all other integers.
If you were doing this iteratively, with loops, you'd initially set diff = INT_MAX. Since this is recursion, INT_MAX is what gets returned when recursion is done.
#include <limits.h>
static inline int min( const int a, const int b ) {
return a < b ? a : b;
}
int minimodiff( const int *a, const size_t size ) {
if( size <= 1 ) {
return INT_MAX;
}
int diff = a[1] - a[0];
return min( minimodiff(a+1, size-1), diff );
}
The recursive approach is a bad idea because extra memory and function calls are used.
Anyway, your question is about avoiding the first difference.
You can use a centinel.
Since the parameter diff is an int variable, it is not possible to obtain a value greater than INT_MAX.
Thus, your first call to minimodiff can be done by giving the value INT_MAX as the argument corresponding to diff.
Besides, the standard header limits.h must be #include'd at top, to make visible the INT_MAX macro.

Why am I getting this strange output on this simple C program? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am working on a personal project where one part of it deals with counting squares and cubes under a certain bound (in this case 10,000). So, I wrote a simple C program I thought would work to verify my results. Here is the little program I put together to see all of the cubes:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
int main() {
double i;
int cubes = 0;
for (i = 1; i < 10000; i++) {
if ( i == cbrt(i) * cbrt(i) * cbrt(i) ) {
printf("%f --- %f\n",i, cbrt(i));
cubes++;
}
}
printf("%i\n", cubes);
return 0;
}
I got the (incorrect) output : 24. If you want to look at this see the problem look at numbers 15 and 20 on the output. Why I am getting the wrong answer (the correct answer is 21) is an entirely different matter. My question arose when I was messing around with my code to try and fix this and I temporarily changed it to this:
int main() {
double i;
int cubes = 0;
for (i = 1; i < 10000; i++) {
double temp = (cbrt(i) * cbrt(i) * cbrt(i));
if ( i == temp ) {
printf("%f -> %f\n", i, temp);
cubes++;
}
}
printf("%i\n", cubes);
return 0;
}
Now, the program is printing every number between 1 and 9999. So, am I missing something ridiculously easy or what is going on? All I did was instead of having cbrt(i)*cbrt(i)*cbrt(i) in the if conditional I set a double variable equal to result and placed that in the conditional. Why is my program doing this?
I am not sure why this got down voted. I feel like this is a legitimate question. Sorry S.O. community...
double cbrt(double x) returns the closest representable cubic root of x.
The inexactness of the result, then cubed, may not exactly equal 'x' again.
Why 2nd program differs:
C is not obliged to perform double math only to double precision. It may use wider (long double). Depending on many things, the 2nd code appears to have done more in long double than the first. With the extra precision, its easy to see that the results, rounded to double appear exact.
C11dr §5.2.4.2.2 9 Except for assignment and cast (which remove all extra range and precision), the values yielded by operators with floating operands and values subject to the usual arithmetic conversions and of floating constants are evaluated to a format whose range and precision may be greater than required by the type.
Why a typical program run (of either code) produces a result of about 3333.
Consider the double numbers from 2 to 4 and 8 to 64. double numbers are logarithmically distributed. There are as many different double from 2 to 4 as 8 to 16 as 16 to 32 as 32 to 64.
So now all 3 sets from 8 to 64 have a cube root of some answer in the 1 set of 2 to 4. Now if we cube the numbers 2 to 4, we get answers in the range 8 to 64. 1 set of numbers mapping into 3 sets. The round trip is not exact. See Pigeonhole principle. IOW: On average, 3 numbers in the range 8 to 64 have the same cubic root. Then the cube of that root will be 1 of the 3 original.
To find the count of the perfect integer cubes 0 to N
unsigned Perfect_Cube_Count(unsigned n) {
if (n == 0)
return 1;
unsigned i;
// overflow not possible
for (i = 0; i*i < n/i; i++);
return i;
}
Or
// valid for 0 <= x <= something_well_over_1e9
double Perfect_Cube_Count_d(double x) {
double y = cbrt(x);
return floor(y) + 1;
}
You probably want, as Andrew guessed, whole-number cube roots. Float math is quite tricky because of rounding errors. Generally you cannot rely on equality but must compare with an error margin.
To solve your problem though I'd construct the 21 cubes beforehand and then iterate over integers, comparing against the pre-constructed cubes. Or is that cheating? ;-)
In Samuel Becket's novel Watt there is a chapter about a Scottish "Math genius" who could in his head compute all integer third roots of integer cubes up to 10000 or so, too!
My uess, is your compiler does an optimization in the second case, eli inating cbrt calls. It just says the result of cbrt is strictly defined by the standard, so it might as well be always thte case that (i == temp)
You can twak this by some command line arguments, and force it to do exactly what is written in the code. As I recall, this should thhe default thing to do for C compilers regarding float arthimetic, but your compiler may think it is smarter than you or something.
EDIT
And yes, this code has nothing to do with finding perfect cubes...
EDIT
Totally not an answer to the question, but as a quick exercise, this I wrote this:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
static unsigned long count_cubes(unsigned long max_n)
{
unsigned long n = 1;
while (n*n*n <= max_n) {
++n;
}
return n-1;
}
int main(int argc, char **argv)
{
unsigned long max_n;
char *p;
if (argc < 2) {
return EXIT_FAILURE;
}
max_n = strtoul(argv[1], &p, 10);
if (max_n < 1 || max_n == ULONG_MAX) {
return EXIT_FAILURE;
}
printf("%lu\n", count_cubes(max_n));
return EXIT_SUCCESS;
}
Note: no need for floating point arithmetic
EDIT
Sorry, I really got into this...
This one can be a bit faster:
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <math.h>
static unsigned long count_cubes(unsigned long max_n)
{
unsigned long n;
if (max_n < 256) {
n = 1;
}
else {
n = cbrtl(max_n) - 1;
}
while (n*n*n <= max_n) {
++n;
}
return n-1;
}
int main(int argc, char **argv)
{
unsigned long max_n;
char *p;
if (argc < 2) {
return EXIT_FAILURE;
}
max_n = strtoul(argv[1], &p, 10);
if (max_n < 1 || max_n == ULONG_MAX) {
return EXIT_FAILURE;
}
printf("%lu\n", count_cubes(max_n));
return EXIT_SUCCESS;
}
EDIT ( last time, I promise... )
To show an explanation of my little loop above, starting at cbrt(max_n)-1, I tried the one suggested by #chux , here are some results with slightly larger numbers:
PerfectCubes(18446724184312856125) == 2642246
which is fine but also
PerfectCubes(18446724184312856125-10) == 2642246
which is totally not fine, since 18446724184312856125 == 2642245^3 , meaning there are 2642245 perfect cubes <= 18446724184312856125-10 .
This also results from inaccuracies in floating point representation. You can try it for yourself, if your computer is somewhat similar to mine:
printf("%f\n", cbrt( 2642245UL * 2642245UL * 2642245UL));
/* prints 2642245.000000 */
printf("%f\n", cbrt( 2642245UL * 2642245UL * 2642245UL - 10UL));
/* prints 2642245.000000 */
These two numbers clearly don't have the same cubic root, yet cbrt returns the same results. In this case, floor doesn't help either. Anyways, one always needs to be very careful using floating point arithmetics. And now I really should go to sleep.

count number using random number rand()

I'm learning C and find rand() is very strange, maybe due to its randomness :p
I've the following code, it always output 1, is there any problem? How would you modify the code to make it do the job?
Cheers,
#include <stdlib.h>
double rand_double()
{
double ret = (double)rand();
return ret/(RAND_MAX+1);
}
int sample_geometric_rv(double p)
{
double q;
int n = 0;
do
{
q = rand_double();
n++;
} while (q >= p);
return n;
}
int main()
{
int ans = sample_geometric_rv(0.1);
printf("Output %d\n", ans);
return 0;
}
You need to seed the random number generator ONCE. Use srand() with a different value everytime you want a different sequence.
In the absence of a seeding, it is as if you had issued a srand(1);
Tipically, the RNG is seeded in main() with the current time as initialization value. The current time as returned by time() is almost guaranteed to be different in every run of the program (it changes once per second).
#include <stdlib.h>
#include <time.h>
int main(void) {
srand(time(0));
/* rest of program; no more calls to srand() */
return 0;
}
Note that if you initialize the RNG with the same number, you get the same sequence. This can be interesting, for example, to repeat the data.
Note too that on different computers, the same initialization number does not need to generate the same numbers.
RAND_MAX here is very likely (2^31)-1 (maximum 32-bit signed integer), so adding 1 causes it to wrap and become negative, which in turn means that p will exceed q for any positive value of p. Change this:
return ret/(RAND_MAX+1);
to this:
return ret/((double)RAND_MAX+1.0);
Seeding the RNG (as previously suggested) is also highly recommended.

Resources