Why doesn't this print a random number? - c

What is the problem with this code?
#include <stdio.h>
#include <stdlib.h>
#include "time.h"
void createNumb(int RandomNumber) {
srand(time(NULL));
int a, b, c, d;
a = rand() % 10 + 0;
b = rand() % 10 + 0;
c = rand() % 10 + 0;
d = rand() % 10 + 0;
while (b == a) {
b = rand() % 10 + 0;
}
while (c == b || c == a) {
c = rand() % 10 + 0;
}
while (d == c || d == b || d == a) {
d = rand() % 10 + 0;
}
RandomNumber = ("%d%d%d%d", a * 1000 + b * 100 + c * 10 + d * 1);
}
int main() {
int x;
createNumb(x);
printf("%d", x);
}
When I run this program, it always give me the result 0.
I want it to print a random 4-digit number (each digit must be unique). What is the problem?

Your createNumb function returns void instead of an int.
You should use srand() only once, so it’s better move it to your main.
Your createNumb function should return a random integer, like this:
int createNumb(void) {
/*
** Simplified for readability.
** Here you would use your function that generates 4 different digits
*/
return rand();
}
int main(void) {
srand(time(NULL))(
int x = createNumb();
printf("%d" , x);
}
Or, if you want createNumb to fill an existing integer, use a pointer:
void createNumb(int *randomNumber) {
/*
** Simplified for readability.
** Here you would use your function that generates 4 different digits
*/
*randomNumber = rand();
}
int main(void) {
int x;
srand(time(NULL))
createNumb(&x); // Passing a pointer to x
printf("%d" , x);
}

There are some problems in your C code, coming from a different language:
use return to return a value from a function and specify the return type before the function name`.
our attempt at formating the number is incorrect and unneeded. Incidentally, RandomNumber = ("%d%d%d%d", a * 1000 + b * 100 + c * 10 + d * 1); uses the operator , that ignores its left operand and evaluates to the right operand, whose value is stored into a local variable with automatic storage duration, and is lost upon function exit. Just use return a * 1000 + b * 100 + c * 10 + d * 1;.
to compute a 4 digit pseudo-random value, you could just use rand() % 10000, but an approach such as your may be needed for more digits or for specific constraints such as unique digits.
to make your results more random, use a faster changing source for srand() such as clock() and initialize the pseudo-random number generator just once int the main() function.
you could use the printf format "%04d" to make display an initial 0 if the result is less than 1000.
Here is a modified version:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int createNumb(void) {
int a, b, c, d;
a = rand() % 10;
b = rand() % 10;
c = rand() % 10;
d = rand() % 10;
while (b == a) {
b = rand() % 10;
}
while (c == b || c == a) {
c = rand() % 10;
}
while (d == c || d == b || d == a) {
d = rand() % 10;
}
return a * 1000 + b * 100 + c * 10 + d;
}
int main() {
int x;
srand(clock());
x = createNumb();
printf("%04d\n", x);
return 0;
}
Note that you can avoid the loops in creatNumb(). Here is a modified version that takes an argument from the command line to produce multiple results.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int createNumb(void) {
int a, b, c, d, bb, cc, dd;
a = rand() % 10;
b = rand() % 9;
c = rand() % 8;
d = rand() % 7;
bb = (b >= a);
cc = (c >= a) + (c >= b);
cd = (d >= a) + (d >= b) + (d >= c);
return a * 1000 + (b + bb) * 100 + (c + cc) * 10 + (d + dd);
}
int main(int argc, char *argv[]) {
int x, n;
srand(clock());
n = (argc > 1) ? strtol(argv[1], NULL, 0) : 1;
while (n-- > 0) {
x = createNumb();
printf("%04d\n", x);
}
return 0;
}
Boolean operators evaluate to 1 when they are true and 0 otherwise. bb = (b >= a); is a short notation for:
bb = 0;
if (b >= a)
bb = 1;
If you want to compute an array of 4 numbers with the given constraint, you should pass a pointer to the destination array as an argument to creatNumb(). Here is a modified version with this approach:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void createNumb(int *dest) {
int a, b, c, d, bb, cc, dd;
a = rand() % 10;
b = rand() % 9;
c = rand() % 8;
d = rand() % 7;
bb = (b >= a);
cc = (c >= a) + (c >= b);
cd = (d >= a) + (d >= b) + (d >= c);
dest[0] = a;
dest[1] = b + bb;
dest[2] = c + cc;
dest[3] = d + dd;
}
int main(int argc, char *argv[]) {
int array[4];
srand(clock());
createNumb(array);
printf("%d%d%d%d\n", array[0], array[1], array[2], array[3]);
return 0;
}
Note that passing an array as a argument to a function actually passes a pointer to its first element: createNumb(array); is equivalent to createNumb(&array[0]);. This process is referred to as arrays decay into pointers in most expression contexts, it is somewhat confusing for beginners but allows for efficient argument passing.

Related

This solution would not accept any floats

Currently on one of the cs50x problem sets 'Cash', which is a simple 'ask for how much change is owed, then calculate how many coins are required' task, so not here asking for a solution but, I don't understand why this won't work.
While it does ask for an input, when I type in a float such as 5.96, it simply hangs. No returns, no errors whatsoever. I have to force it shut. The other thing is the while loop doing the same when set to 0, which is the intended way of doing things in order to get the exact number of coins.
I know how inefficient this code is and there are simpler ways of doing things. I just wish to understand the whys in order to avoid making the same mistakes moving on. Thanks.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
// changes and other containers
int p = 1;
int n = 5;
int d = 10;
int q = 25;
int x = 0;
float c;
// get how much change is owed in float
do
{
c = get_float("Change owed: ");
}
while (c < 0);
// int conversion to avoid imprecision
int a = round(c * 100);
// 1 because 0 spits out an unknown error
while (a >= 1)
{
// if the converted amount is bigger than a quarter
if (a >= q)
{
// x = number of coins, a = amount left
x = a / q;
a = a % q;
}
else if (a >= d)
{
x = x + a / d;
a = a - a % d;
}
else if (a >= n)
{
x = x + a / n;
a = a - a % n;
}
else
{
x = x + a / p;
a = a - a % p;
}
}
printf("%i\n", x);
printf("%i\n", a);
}
Thanks to WhozCraig, I figured out that my logic was at fault.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void)
{
// changes and other containers
int p = 1;
int n = 5;
int d = 10;
int q = 25;
int x = 0;
float c;
// get how much change is owed in float
do
{
c = get_float("Change owed: ");
}
while (c < 0);
// int conversion to avoid imprecision
int a = round(c * 100);
// 1 because 0 spits out an unknown error
while (a >= 1)
{
// if the converted amount is bigger than a quarter
if (a >= q)
{
// x = number of coins, a = amount left
x = a / q;
a = a % q;
}
else if (a >= d)
{
x = x + a / d;
a = a % d;
}
else if (a >= n)
{
x = x + a / n;
a = a % n;
}
else
{
x = x + a / p;
a = a % p;
}
}
printf("%i\n", x);
printf("%i\n", a);
}

Using debugger to find integer values

For this assignment I am supposed to use the debugger in Visual Studios, I kind of understand how to use it but i cant figure it out completely. For the first part of the code, it asks for all values of a,b, and c. I put my debugger to start right before it starts and then right after it ends. I run it through using the F10 key. I go through it once and I get a=6, b=3, c=6. Then once I go through it again i get different values, however I want to view those values as a list. Is that possible?
//THIS IS THE CODE.
#include<stdio.h>
void func1(int a, int b, int c)
{
//Track all values of a, b, and c
printf("%d %d %d\n",a,b,c);
a = b + b;
printf("%d %d %d\n",a,b,c);
}
int func2(int x)
{
//Track all values of x
printf("%d\n",x);
for (x = 7; x < 12; x += 1)
{
printf("%d", x + 10);
}
return(x);
}
int func3(int x)
{
x = x + 51;
return(x);
}
int main()
{
int a,b,c;
//Track each array index value
int arr[5];
a = 7;
b = 3;
c = 3;
func1(5, 3, 6);
func2(c);
b = func2(c);
for (c = 0; c < 5; c += 1)
{
arr[c] = c + 2;
}
for (b = 22; b > 7; b += -1)
{
arr[b + func3(a)] = a + b + c;
printf("%d\n", b);
}
for (b = 0; b < 5; b += 1)
{
printf("%d\n", arr[b]);
}
return(0);
}
arr[b + func3(a)]
Before debugging further fix the bug in the code.
Here you have array out of bound access which will lead to undefined behavior.
You are trying to access arr[22 + x] where as the size of the array is 5.

C RSA key generation program

I'm trying to hone my skills in C as well as get a better understanding of RSA, so I took it upon myself to try and make my own generator. I've generated both base prime numbers, p and q, calculated the value o = (p-1) * (q-1). These are working correctly. The next steps is where I'm having issues. I'm pretty close, but I can't seem to find the correct way to calculate the encryption and decryption factors of the 1 mod r value. Any help for generating this would be awesome. (or just write the code yourself and i can learn off that) Plus if there's any other issues let me know!
Here's my code:
#include<stdio.h>
#include<time.h>
#include"../hdr/test.h" //fake header just to satisfy my makefile
//Receives: number that was generated in main
//Returns: 1 for false, 0 for true
//Purpose: checks if the numbers is prime and returns 1 or 0
int isPrime(int number)
{
if (number <= 1)
return 0;
int i;
for (i=2; i<number; i++) {
if (number % i == 0)
return 0;
}
return 1;
}
/*Receives: an integer ((p-1) * (q-1))
Returns: integer (e)
Purpose: Generates the relatively prime number to ((p-1) * (q-1))*/
int gen_E(int o)
{
puts("Generating E...");
int e;
do {e = rand() % o;} while (GCD(e, o) != 1);
return e;
}
/*Receives: integer E and O from the main
Returns: newly calculated integer D
Purpose: Generates D for the private key*/
int gen_D(int e, int o)
{
puts("Generating D...");
int e = a;
int o = b;
int phin, d;
for (phin = 1; phin < o; phin ++)
for (d = 1; d < 998001; d ++)
if ((e * d) == (o * phin) + 1) return d;
}
/*Receives: integer E and O from main
Returns: greatest common divisor's remainder
Purpose: Calculate if the two numbers share a divisor.*/
int GCD(int e, int o)
{
int c;
while (e != 0) {
c = e; e = o%e; o = c;
}
return o;
}
int main()
{
puts("Generating Prime P...");
srand(time(NULL));
int p = rand() % 1000;
while (isPrime(p) != 1) {
p = rand() % 1000;
}
puts("Generating Prime Q...");
int q = rand() % 1000;
while (isPrime(q) != 1) {
q = rand() % 1000;
}
int n = p * q;
int o = (p - 1) * (q - 1);
int e = gen_E(o);
int d = gen_D(e, o);
printf("p: %d\nq: %d\nn: %d\no: %d\ne: %d\nd: %d\n", p, q, n, o, e, d);
printf("KU = {%d, %d}\n", e, n);
printf("KR = {%d, %d}\n", d, n);
}
You will need a function to compute GCD (greatest common divider) of two numbers. After that, choose random e such that GCD(e,o) == 1.
Of course in practice it's probably more complicated than that but for homework it's fine.

Feige Fiat Shamir Scheme not working

I'm trying to implement the Feige Fiat Shamir Identification Scheme in C (Arduino) and it works, but only when e = 0. When e = 1 it doesn't work.
How can I make it work?
#include <Wire.h>
int getGCD(int a, int b)
{
int c;
while (a != 0)
{
c = a;
a = b % a;
b = c;
}
return b;
}
int getCoprime(int n)
{
int coprime;
do
{
coprime = random(1, n);
}
while (getGCD(n, coprime) != 1);
return coprime;
}
//Preparation
int n = 7 * 3;
int s = getCoprime(n);
int v = (s * s) % n;
void loop ()
{
e = random(0, 2);
r = random(1, n);
int y = (r * (int)pow(s, e)) % n;
int x = (r * r) % n;
int ysqmodn = y * y % n;
int test = (x * (int)pow(v, e)) % n;
if(ysqmodn == test)
{
Serial.print("The current ICC matches. \n");
}
else
{
Serial.print(String(e));
Serial.print("\n");
}
delay(500);
}
It does work when e==1. When e==0 the computation is trivial, since s and v fall out due to power of 0 always being 1. This is the code copied and altered only enough to get it to compile.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
int random (int low, int high) {
return low + rand() % (high - low);
}
int getGCD(int a, int b) {
int c;
while (a != 0)
{
c = a;
a = b % a;
b = c;
}
return b;
}
int getCoprime(int n) {
int coprime;
do
{
coprime = random(1, n);
}
while (getGCD(n, coprime) != 1);
return coprime;
}
int main(void) {
int e, x, y, r, n, s, v, test, ysqmodn;
srand((unsigned)time(NULL));
n = 7 * 3;
s = getCoprime(n);
v = (s * s) % n;
e = random(0, 2);
r = random(1, n);
printf("n=%d, s=%d, e=%d, r=%d\n", n,s,e,r);
y = (r * (int)pow(s, e)) % n;
x = (r * r) % n;
ysqmodn = y * y % n;
test = (x * (int)pow(v, e)) % n;
if(ysqmodn == test)
printf("The current ICC matches. \n");
else
printf("%d\n", e);
return 0;
}
Sample results:
n=21, s=2, e=1, r=2
The current ICC matches.
n=21, s=11, e=0, r=12
The current ICC matches.
n=21, s=8, e=1, r=14
The current ICC matches.
n=21, s=17, e=1, r=13
The current ICC matches.
n=21, s=1, e=0, r=9
The current ICC matches.
n=21, s=4, e=0, r=13
The current ICC matches.

floating point exception in c program

while running this code I am getting floating point exception pls explain why it is coming so.
#include <stdio.h>
int gcd(long int, int);
int main() {
int t, n, a, i;
long int abc;
scanf("%d", &t);
while (t--) {
abc = 1;
scanf("%d", &n);
abc = n * (n - 1);
for (i = n - 2; i > 1; i--) {
a = gcd(abc, i);
abc = ((abc * i) / a);
}
printf("%ld \n", abc);
}
return 0;
}
int gcd(long int a, int b) {
if (b == 0)
return a;
else {
return (b, a % b);
}
}
The else part in gcd function is bogus. You probably wanted to call gcd recursively and instead you are returning a % b. And as a result if a % b == 0 you divide by 0 on line 13.
The expression (b, a % b) is evaluated as two subexpressions separated by comma operator. The value of b is forgotten and the value of the whole expression becomes a % b.
The correct version:
int gcd(long int a, int b) {
if (b == 0)
return a;
else {
return gcd(b, a % b);
}
}
You should change a few things:
1) if(a == 0) instead of b==0 and return variable b
2) Use recursion gcd(b%a, a)
if (a == 0)
return b;
else {
return gcd(b%a, a);
}
And you can also use this short version
return a ? gcd(b%a,a) : b;
Proof:
We have m = n * (m div n) + m Mod n.
This equation is correct even if n = 1, because m div 1 = m and m mod 1 =0.
If n and m mod n it's multiple of d, also m is multiple of d, because n * (m div n) and m mod n / d.
On the other hand if m and n is multiple of e, to because m mod n = m -n * (m div n) is also multiple of e.

Resources