0

I want to generate random number between two numbers in C (Kernel). It's easy in C with standard library, but in C without library, I just found this links: link 1, link 2 and I don't know how can I use the codes are in links.

I cannot show my code. Because my code is too long (+1000 lines of code).

Edit

Here is my incomplete code:

#include <lib.h>

int rand()
{
    unsigned long int next = 1;
    next = next * 1103515245 + 12345;
    return (unsigned int)(next / 65536) % (RAND_MAX + 1);
}

int rrand(int min, int max)
{
    /* incomplete */
}

lib.h:

#ifndef _LIB_H
# define _LIB_H
#endif

#ifdef _LIB_H
# ifndef _DEF_H /* this line isn't important for this question */
#  include <def.h> /* this line isn't important for this question */
# endif

# define RAND_MAX 32767
extern int rand();
extern int rrand(int min, int max);
extern void *malloc(size_t size); /* this line isn't important for this question */
extern int atoi(char *str); /* this line isn't important for this question */
extern char *itoa(int value, char *str, int base); /* this line isn't important for this question */
#endif

Edit 2

I can compile my code without error.

sbh
  • 65
  • 1
  • 9
  • 1
    What's wrong with the questions/answers in the links? – Jabberwocky May 12 '21 at 07:00
  • @Jabberwocky I cannot generate random number using answers in questions. I don't know how can I generate random number e.g. between 5 and 25 using answers in questions. – sbh May 12 '21 at 07:09
  • @Jabberwocky Is there any problem in my question that needs to be edited? – sbh May 12 '21 at 07:12
  • 2
    So why are you unable to use the code proposed in the links? What did you try? Are you unable to compile the code? Does it run but the results you get are not the results you expect? Read this: [ask] and this: [mcve]. – Jabberwocky May 12 '21 at 08:19
  • Related: https://xkcd.com/221/ – pmg May 12 '21 at 08:19
  • 2
    If you're using 1000+ lines of code for a function that generates pseudo random numbers and a function that selects from a range you're overdoing it. – pmg May 12 '21 at 08:22
  • Suggestion: do not use Standard identifiers (`RAND_MAX`, `rand`, `malloc`, `atoi`) in your code unless you're writing a Standard library. – pmg May 12 '21 at 08:28
  • @pmg No, my kernel can: 1. Clear screen if input is `clr`, 2. Change cursor shape if input is `cursorset cursorcode`, 3. Print on screen if input is `echo "String`, 4. reboot if input is `reboot`, 5. shutdown if input is `shutdown`, 6. Open console calculator if input is `calc`. I need to generate random number between two numbers for my calculator. – sbh May 12 '21 at 08:30
  • @pmg I not making standard library, but I making a library for my kernel. Do you want me place my code at GitHub? – sbh May 12 '21 at 08:34

1 Answers1

0

I usually do a function to generate a random number up to, and excluding, n

unsigned randto(unsigned n) {
    unsigned r, hi = (RAND_MAX / n) * n; // avoid
    do r = rand(); while (r >= hi);      // bias
    return r % n;
}

With this function (and, of course, rand()), you can easily write your rrand()

unsigned rrand(unsigned lo, unsigned hi) {
    return lo + randto(hi - lo + 1);
}
pmg
  • 106,608
  • 13
  • 126
  • 198
  • Where is assert() function? – sbh May 12 '21 at 08:37
  • assert not needed, removed... but don't go calling `rrand(100, 10);` – pmg May 12 '21 at 08:37
  • error: ‘hi’ undeclared (first use in this function) – sbh May 12 '21 at 08:43
  • copy/paste error :-) https://ideone.com/XMs2st – pmg May 12 '21 at 08:46
  • Sorry, I forgot one line. – sbh May 12 '21 at 08:49
  • I compiled it without error, but it seems like rrand() only generates one number. – sbh May 12 '21 at 08:54
  • The error you're experiencing is in your version of `rand()`: try it: `for (unsigned k = 0; k < 100; k++) { printf("%d ", rand()); }` – pmg May 12 '21 at 08:55
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/232272/discussion-between-ariankg-and-pmg). – sbh May 12 '21 at 08:59
  • Please check discussion. – sbh May 18 '21 at 09:24
  • copy/paste error surely. The last version with `static` I posted on ideone works flawlessly. – pmg May 18 '21 at 09:35
  • I think you didn't get it. For example, if I use `rrand(first_input, second_input)`, in first output (First input: 1, Second input: 10), I can see [2, 3, 7]. But after a reboot, second output (First input: 1, Second input: 10) is [2, 3, 7] again. Note that it was just an example. – sbh May 18 '21 at 09:45
  • Ah... `static unsigned long int next = 1; // <============== static keyword` is to blame. You want to initialize (*seed*) the random number generator with a different value everytime. Most people use `time(0)` to initialize with number of seconds since Unix epoch; maybe you can use the same or use a counter outside your program (in a file) or some other way to keep seeding the `next` without recompiling. – pmg May 18 '21 at 09:55
  • `time(0)`? I have no standard library in my kernel. How can I use `time()`? – sbh May 18 '21 at 09:59
  • "Anyone who considers arithmetical methods of producing random digits is, of course, in a state of sin." -- John von Neumann (1951) from [wikipedia article on PRNG](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) – pmg May 18 '21 at 10:04