random() function only spitting out big numbers - c

I am using the random() function, and I was wondering if there is a reason that I'm always getting 8-10 digit numbers. I just want to make sure there isn't something wrong with my program. Thanks.
Here's the function:
void random_array(int* p, int size) {
/*seed random number generator */
srandom(time(NULL));
int i;
for(i = 0; i < size; i++)
*(p+i) = random();
}

Well, mathematically the chance that you will get a big number is a lot more than the chance for a (relatively) small one. For instance, if you pick a random number with (1-4) digits, the chance that it would be in the range (0-99) would be only 1 %.
With that said, if you want smaller numbers, you can take the random modulo some certain number:
a = random() % 100; // this will give you a random number from 0 to 99
b = 10 + random() % 15; // random number from 10 to 24

Number of 8-10 digits numbers: 10,000,000,000 - 100,000,000 = 9,900,000,000 (9.9 billion)
Number of 0-7 digit numbers: 10,000,000 (10 million)
In other words, there are 990 8-10 digit numbers for every 1 0-7 digit number. Therefore, you can expect to get about 1 0-7 digit number for every 990 8-10 digit numbers.
Put simply, it's because there are more of them.

How large a number were you expecting to receive from random()?
If you want to limit the size of the number generated, simply use a modulus operator to limit the result to the remainder (in the example below a number from 0 to 999):
*(p+i) = random() % 1000;

Mathematically it is likely since big numbers are..well.. more than small ones, so yes. It is much more likely to get such a number.
To generate a custom-interval random number use something like
http://ideone.com/bWbBgJ
#include <stdlib.h>
#include <stdio.h>
// Generate random numbers in the min-max interval
void random_array(int* p, int size, int min, int max) {
/*seed random number generator */
srandom(time(NULL));
int i;
for(i = 0; i < size; i++)
*(p+i) = (random() % max) + min;
}
int main(void) {
int array[3];
random_array(array, 3, 0, 12);
printf("%d\n", array[0]);
printf("%d\n", array[1]);
printf("%d\n", array[2]);
return 0;
}

Related

Sum digits of number [duplicate]

This question already has answers here:
Find the sum of digits of a number(in c)
(6 answers)
Closed 2 years ago.
Hello i need problem with this task in C language. If anyone had a similar problem it would help me.
The task is:
Write a program that loads the numbers a and b (a <b), then finds and prints the numbers from the segment of [a, b] and prints the sum of the digits of each number.
I wrote for three issues, for example:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main()
{
int n1,n2,sum=0,a,b,k,n3;
scanf("%d",&a);
scanf("%d",&b);
for(k=a;k<=b;k++)
{
n1=k%10;
n2=(k/10)%10;
n3=k/100;
sum=n1+n2+n3;
printf("%d\n",sum);
}
}
The problem arises when I enter a larger than three-digit number, how to make for any number, no matter if it is two-digit, three-digit, four-digit ...
Well the way you solve this issue depends on the exact requirements. Given that you only have ints here I would use the following though it is by no meand production code
int main() {
int a = whatever;
int b = whatever;
char* a_as_s = itoa(a);
char* b_as_s = itoa(b);
int sum_of_a = 0;
int sum_of_b = 0;
for(int i = 0; a_as_s[i]; i++)
sum_of_a += atoi(a_as_s[i]);
for(int i = 0; b_as_s[i]; i++)
sum_of_b += atoi(b_as_s[i]);
}
That should calculate the sum of digits for arbirary lengths - the rest of your code seems fine
You've already solved the iterating part so as people have suggested in the comments all you need now is a way to sum the digits of an arbitrary integer. I've modified your solution with my take on the problem. I'm pretty sure there is a more elegant/efficient way to do this, so I'd suggest you also check out the links people have provided in the comments. Anyhow here is my take:
#include <stdio.h>
int maxPowOf10(int num)
{
int divisor = 1;
for(;;)
{
if(num / divisor == 0)
{
break;
}
divisor *= 10;
}
return divisor / 10;
}
int sumOfDigits(int num)
{
int sum = 0;
for(int divisor = maxPowOf10(num); divisor >= 1; divisor /= 10)
{
int tmp = num / divisor;
sum += tmp;
num -= tmp * divisor;
}
return sum;
}
int main()
{
int n1,n2,sum=0,a,b,k,n3;
printf("Insert a: ");
scanf("%d",&a);
printf("Insert b: ");
scanf("%d",&b);
printf("Result\n");
for(k=a;k<=b;k++)
{
sum = sumOfDigits(k);
printf("number: %d sum of its digits: %d\n", k, sum);
}
return 0;
}
The approach is fairly straightforward. To find the sum of the digits, first you determine what is the largest power of 10 that still features in the number. Once that is found we can just divide by the largest power of 10 and add the result to sum. The trick is that, after that, we have to remove the part of the number that is described by the decimal place we are at. So we don't count it again. Then, you keep repeating the process for ever decreasing powers of 10. In the end you have the complete sum.
To illustrate this on 152 for example:
a) The largest power of 10 in 152 is 100.
b1) We divide 152 by 100 and get 1. We add 1 to sum. We also decrease the number to 52 (152 - 100)
b2) We divide 52 by 10 and get 5. We add 5 to sum. We decrease the number to 2 (52 - 50).
b3) We divide 2 by 1 and get 2. We add 2 to sum. We decrease the number to 0 (2 - 2).
Point a describes the method maxPowOf10
Point b describes the method sumOfDigits

C program which is finding "happy" nums recursively

Hello guys i am trying to implement a program which is finding the happy numbers were between two numbers A and B.
Summing the squares of all the digits of the number, we replace the number with the outcome, and repeat the process. If after some steps the result is equal to 1 (and stay there), then we say that the number N is **<happy>**. Conversely, if the process is repeated indefinitely without ever showing the number 1, then we say that the number N is **<sad>**.
For example, the number 7 is happy because the procedure described above leads to the following steps: 7, 49, 97, 130, 10, 1, 1, 1 ... Conversely, the number 42 is sad because the process leads to a infinite sequence 42, 20, 4, 16, 37, 58, 89, 145, 42, 20, 4, 16, 37 ...
I try this right down but i am getting either segm faults or no results.
Thanks in advance.
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
printf("%ld %d\n",A,npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == 1 || A[0] == 7)
printf("%c\n",A[0]);
printf("%s\n",A);
return;
}
long sum = 0 ;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = atoi(&A[i]);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Thanks for your time.
by the definition of your program sad numbers will cause your program to run forever
Conversely, if the process is repeated indefinitely
You need to add a stopping condition, like if I have looped for 1000 times, or if you hit a well known non terminating number (like 4) (is there a definite list of these? I dont know)
I find this solution tested and working..
Thanks for your time and I am sorry for my vagueness.
Every advice about this solution would be welcome
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
void happy( char * A, int n);
int numPlaces (long n);
int happynum = 0;
int main(void)
{
long A,B;
int npA;
char *Ap;
printf("Give 2 Numbers\n");
scanf("%li %li",&A,&B);
npA = numPlaces(A);
Ap = malloc(npA);
//Search for happy numbers from A to B
do{
sprintf(Ap, "%ld", A);
happy(Ap,npA);
if (happynum ==1)
printf("%s\n",Ap);
A++;
if ( npA < numPlaces(A) )
{
npA++;
Ap = realloc(Ap, npA);
}
}while( A <= B);
}
//Finds happy numbers
void happy( char * A, int n)
{
//Basic Condition
if ( n == 1)
{
if (A[0] == '3' || A[0] == '6' || A[0] == '9')
{
happynum = 0;
}
else
{
happynum = 1;
}
return;
}
long sum = 0;
char * sumA;
int nsum;
int Ai;
//Sum the squares of the current number
for(int i = 0 ; i < n;i++)
{
Ai = (int)(A[i]-48);
sum = sum + (Ai*Ai);
}
nsum = numPlaces (sum);
sumA = malloc(nsum);
sprintf(sumA, "%li", sum);
happy(sumA,nsum);
free(sumA);
}
//Count digits of a number
int numPlaces (long n)
{
if (n < 0) return 0;
if (n < 10) return 1;
return 1 + numPlaces (n / 10);
}
Your code uses some questionable practices. Yoe may be misguided because you are concerned about performance and memory usage.
When you allocate memory for the string, you forget to allocate one character for the null terminator. But you shouldn't be allocating, re-allocating and freeing constantly anyway. Dynamic memory allocation is expensive compared to your other operations.
Your limits are long, which may be a 32-bit or 64-bit signed integer, depending on your platform. The maximum number that can be represented with e 64-bit signed integer is 9,223,372,036,854,775,807. This is a number with 19 digits. Add one for the null terminator and one for a possible minus sign, so that overflow won't hurt, you and use a buffer of 21 chars on the stack.
You probably shouldn't be using strings inthe first place. Use the basic code to extract the digits: Split off the digit by taking the remainder of a division by 10. Then divide by 10 until you get zero. (And if you use strings with a fixed buffer size, as described above, you don't have to calculate the difits separately: sprintf returns the number of characters written to the string.
Your functions shouldn't be recursive. A loop is enough. As pm100 has noted, you need a termination criterion: You must keep track of the numbers that you have already visited. Each recursive call creates a new state; it is easier to keep an array, that can be repeatedly looked at in a loop. When you see a number that you have already seen (other than 1, of course), your number is sad.
Happy and sad numbers have this property that when your sum of squares is a number with a known happiness, the original number has this happiness, too. If you visit a known das number, the original number is sad. If you visit a known happy number, the original number is happy.
The limits of your ranges may ba large, but the sum of square digits is not large; it can be at most the number of digits times 81. In particular:
type max. number number of max. square sum dss
int 2,147,483,647 1,999,999,999 730
uint 4,294,967,295 3,999,999,999 738
long 9,223,372,036,854,775,807 8,999,999,999,999,999,999 1522
ulong 18,446,744,073,709,55,1616 9,999,999,999,999,999,999 1539
That means that when you take the sum of digit squares of an unsigned long, you will get a number that is smaller than 1540. Create an array of 1540 entries and mark all known happy numbers with 1. Then you can reduce your problem to taking the sum of digit squares once and then looking up the happiness of the number in this array.
(You can do the precalculation of the array once when you start the program.)

Print a random number from my own array

I've been trying to understand how to print out some random numbers from my own array, dont confuse this with that i want to generate random numbers into an array, which is not what im trying to accomplish.
However, my code is like this
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
srand(time(NULL));
int myarray[] = { 2, 5, 10 };
//Its here where i dont know how to use rand() in to make the program generate one random number from my array, either 2, 5 or 10. I've tried, but failed.
return 0;
}
Ive not found any similar question to this either, so would greatly appreciate some help.
int number = myarray[rand() % 3];
This generates a random number : 0 1 2 and then accesses that element from the array.
You can use the following formula to generate a random number within a range:
rnd(min, max) = (rand() % (max - min)) + min;
In your case you, min = 0 and max = 3, which gives you rand() % 3.
The other answers use rand() % 3 for generating a (pseudo-)"random" number between 0 and 2 (including both). This might work for you, but is not really random, since the numbers returned by rand() between RAND_MIN and RAND_MAX are not distributed uniformly in terms of their divisibility through a given number n (because the equivalence classes of the modulo relation have unequal amounts of members if RAND_MAX is not a multiple of n).
A better algorithm for getting (pseudo-)random numbers in a given range is:
int RangeRandom(int min, int max) {
int n = max - min + 1;
int remainder = RAND_MAX % n;
int x;
do
{
x = rand();
} while (x >= RAND_MAX - remainder);
return min + x % n;
}
You can then use the function RangeRandom as follows:
int myArray[] = { 0, 3, 5 };
printf("%d", myArray[RangeRandom(0, 2)]);

Tricky and confusing C program about divisor sum and perfect numbers

The assignment is :
Write a program that calculates the sum of the divisors of a number from input.
A number is considered perfect if the sum of it's divisiors equal the number (ex: 6 = 1+2+3 ;28 = 1 + 2 + 4 + 7 +14).
Another definition:
a perfect number is a number that is half the sum of all of its positive divisors (including itself)
Generate the first k perfect numbers (k<150).
The main problem with this is that it's confusing the two asking points don't really relate.
In this program i calculated the sum of divisors of an entered number, but i don't know how to relate it with the second point (Generate the first k perfect numbers (k<150)).
#include <stdio.h>
#include <stdlib.h>
main()
{
int x,i,y,div,suma,k;
printf("Introduceti numarul\n"); \\enter the number
scanf("%d",&x);
suma=0; \\sum is 0
for(i=1;i<=x;i++)
{
if(x%i==0)
suma=suma+i; \\sum=sum+i;
}
printf("Suma divizorilor naturali este: %d\n",suma); \\the sum of the divisors is
for(k=1;k<150;k++) \\ bad part
{
if (x==suma)
printf("%d",k);
}
}
Suppose you have a function which can tell whether a given integer is perfect or not:
int isPerfect(int);
(function body not shown)
Now your main program will look like:
int candidate;
int perfectNumbers;
for(candidate = 1, perfectNumbers = 0; perfectNumbers < 150; candidate++) {
if (isPerfect(candidate)) {
printf("Number %d is perfect\n", candidate);
perfectNumbers++;
}
}
EDIT
For the same program without functions:
int candidate;
int perfectNumbers;
for(candidate = 1, perfectNumbers = 0; perfectNumbers < 150; candidate++) {
[... here your algorithm to compute the sum of the divisors of "candidate" ...]
if (candidate*2 == sum_of_divisors) {
printf("Number %d is perfect\n", candidate);
perfectNumbers++;
}
}
EDIT2: Just a note on perfect numbers
As noted in the comments section below, perfect numbers are very rare, only 48th of them are known as of 2014. The sequence (A000396) also grows very fast: using 64-bit integers you'll be able to compute up to the 8th perfect number (which happen to be 2,305,843,008,139,952,128). In this case the variable candidate will wrap around and start "finding" "new" perfect numbers from the beginning (until 150 of them are found: actually 19 repetitions of the only 8 findable in 64-bit integers). Note though that your algorithm must not choke on a candidate equals to 0 or to negative numbers (only to 0 if you declare candidate as unsigned int).
I am interpreting the question to mean generate all numbers under 150 that could are perfect numbers.
Therefore, if your program works for calculating perfect numbers, you keep calculating them until the starting number is >= 150.
Hope that makes sense.
Well, here's my solution ..
First, you have to make a reliable way of getting divisors.Here's a function I made for that:
size_t
getdivisors(num, divisors)
long long num;
long long *divisors;
{
size_t divs = 0;
for(long long i = num; i > 0; --i)
if (num%i == 0)
divisors[divs++] = i;
return divs;
}
Second, you need to check if the number's divisors match the perfect number's divisors properties (the sum of them is half the number).
Here's a second function for that:
bool
isperfect(num)
long long num;
{
long long divisors[num/2+1];
size_t divs = getdivisors(num, divisors);
if (divs == 0)
return false;
long long n = 0;
for(int i = 1; i < divs; ++i)
n += divisors[i];
return (n == num);
}
Now, from your question, I think you need to print all perfect numbers less than 150, right ?
See this:
int
main(argc, argv)
int argc;
char ** argv;
{
for(int i = 1; i < 150; ++i)
if (isperfect(i))
printf("%d is perfect.\n", i);
return 0;
}
I hope that answers your question ..

Array of random numbers using C program

Im new to C program and I am required create 100 random numbers between 50 and 70, and store them in an array of double. How do I start?
Create an array:
int my_array[100];
Seed the random number generator
srand(0);
Loop over your array and fill it up!:
int i;
for (i = 0; i < 100; i++) {
my_array[i] = rand();
}
That's a start. However, the range of rand() is much larger than the range of random numbers you want. There are many ways to narrow the range. If you don't care about the numbers being perfectly random, you can use the modulo operator, where 13 % 10 = 3.
This is for ints. I want to leave some fun for the reader.
If the number is between 50 and 70, then I would say, try modulo and the rand() function of c.
So firstly since you will want yo use random numbers, I would advice including the standard library.
Do:
#include <stdlib.h>`
double bal[100];
for (int f = 0; f < 100 ;f++) {
bal[f] = (rand() % 20) + 50;
}
The reason why I modulo 20 is because the difference between 50 and 70 is 20 so, if you assume 50 is zero then 70 will be 20 and so any number we will produce will be between these numbers. Hope it helps! */
you can use this to range the rand function:
rand() % (max_number + 1 - minimum_number) + minimum_number
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void gen_random_numbers(int *array, int len, int min, int max){
for (int i = 0; i < len; i++)
array[i] = rand() % (max - min + 1) + min;
}
int main() {
system("cls");
srand(time(0));
int numbers[100] = {};
gen_random_numbers(numbers, 100, 50, 70);
return 0;
}

Resources