Hi stackoverflow community! I'm having some problems with my code. I'm currently a student so basically I'm a beginner. Using Euclidean Algorithm, the code shown below should divide and divide two numbers until the quotient reach 0 but it just stops at the last dividing process just before the quotient turns 0. I don't know if the program crashes because of this. Hoping for a beginner-friendly reply from you guys. Thanks! (sorry if there's already an existing question like this)
Here's the code:
int quotient,quotient2,remainder,remainder2,x,y;
int foo()
{
printf("Enter a number: ");
scanf("%d", &x);
printf("Enter another number: ");
scanf("%d", &y);
if(y >= x){
quotient2 = y / x;
remainder2 = y % x;
printf("%d = %d(%d) + %d\n", y,x,quotient2,remainder2);
if(quotient2 != 0){
do{
y = x;
x = remainder2;
quotient2 = y / x;
remainder2 = y % x;
printf("%d = %d(%d) + %d\n", y,x,quotient2,remainder2);
} while(quotient2 != 0);
}
} else if(x > y){
quotient = x / y;
remainder = x % y;
printf("%d = %d(%d) + %d\n", x,y,quotient,remainder);
if(quotient != 0){
do{
x = y;
y = remainder;
quotient = x / y;
remainder = x % y;
printf("%d = %d(%d) + %d\n", x,y,quotient,remainder);
} while(quotient != 0);
}
}
system("pause");
return 0;
}
If your "Euclidean algorithm" is computing the GCD of two numbers, here is one way to do it. Note it does not divide by 0, it stops when the divisor would be 0.
So the point is, rather than guard against dividing by 0, that's the iteration's end condition anyway.
#include <stdio.h>
unsigned gcd(unsigned x, unsigned y) {
unsigned z;
if (x == 0 || y == 0) {
return 0;
}
while ((z = y % x) != 0) {
y = x;
x = z;
}
return x;
}
int main(void)
{
printf("20 ~ 20 : %u\n", gcd(20, 20));
printf("20 ~ 0 : %u\n", gcd(20, 0));
printf(" 0 ~ 20 : %u\n", gcd( 0, 20));
printf("20 ~ 16 : %u\n", gcd(20, 16));
printf("16 ~ 20 : %u\n", gcd(16, 20));
printf("20 ~ 15 : %u\n", gcd(20, 15));
printf("15 ~ 20 : %u\n", gcd(15, 20));
printf(" 1 ~ 2 : %u\n", gcd( 1, 2));
printf(" 2 ~ 1 : %u\n", gcd( 2, 1));
return 0;
}
Program output:
20 ~ 20 : 20
20 ~ 0 : 0
0 ~ 20 : 0
20 ~ 16 : 4
16 ~ 20 : 4
20 ~ 15 : 5
15 ~ 20 : 5
1 ~ 2 : 1
2 ~ 1 : 1
Note there is no need to swap the arguments. The algorithm works no matter which way round they are.
Notice that with x = remainder2;, x could take on the value of 0. Then the next quotient2 = y / x; remainder2 = y % x; both perform operations (divide by 0 and remainder 0) which are both undefined behavior. The program crash is certainly due to this.
if(y >= x){
quotient2 = y / x;
remainder2 = y % x;
printf("%d = %d(%d) + %d\n", y,x,quotient2,remainder2);
if(quotient2 != 0){
do{
y = x;
x = remainder2;
quotient2 = y / x;
remainder2 = y % x;
printf("%d = %d(%d) + %d\n", y,x,quotient2,remainder2);
} while(quotient2 != 0);
}
As code is swapping the roles of x,y with each operation, code could simplify to: (Also see What is gcd(0,a)gcd(0,a), where a is a positive integer?
unsigned gcd(unsigned a, unsigned b) {
while (b) {
a %= b;
if (a == 0) return b;
b %= a;
}
return a;
}
Related
I need to write a program that takes 2 digits(X and n) and then prints X with last n digits of X reversed.
For example
Input: 12345 3
Output: 12543
Input: 523 2
Output: 532
I already wrote a control mechanism for checking n is greater or equal than the number of digits of X
For example if inputs are 6343 and 7, program prints that inputs should be changed and takes input again.
My main problem is I couldn't find an algorithm for reversing last n digits. I can reverse any int with this code
int X, r = 0;
printf("Enter a number to reverse\n");
scanf("%d", &n);
while (X != 0)
{
r = r * 10;
r = r + n%10;
X = X/10;
}
printf("Reverse of the number = %d", r);
But I couldn't figure how two reverse just last digits. Can you give me any idea for that?
I couldn't figure how to reverse just last digits
Separate the number using pow(10,n) - see later code.
unsigned reverse_last_digits(unsigned x, unsigned n) {
unsigned pow10 = powu(10, n);
unsigned lower = x%pow10;
unsigned upper = x - lower;
return upper + reverseu(lower, n);
}
Create a loop that extracts the least-significant-digit (%10) and builds up another integer by applying that digit. (y = y*10 + new_digit)
unsigned reverseu(unsigned x, unsigned n) {
unsigned y = 0;
while (n-- > 0) {
y = y*10 + x%10;
x /= 10;
}
return y;
}
For integer type problems, consider integer helper functions and avoid floating point functions like pow() as they may provide only an approximate results. Easy enough to code an integer pow().
unsigned powu(unsigned x, unsigned expo) {
unsigned y = 1;
while (expo > 0) {
if (expo & 1) {
y = x * y;
}
expo >>= 1;
x *= x;
}
return y;
}
Test
int main() {
printf("%u\n", reverse_last_digits(12345, 3));
printf("%u\n", reverse_last_digits(523, 2));
printf("%u\n", reverse_last_digits(42001, 3));
printf("%u\n", reverse_last_digits(1, 2));
}
Output
12543
532
42100
10
Code uses unsigned rather than int to avoid undefined behavior (UB) on int overflow.
It is an easy one.
1. let say the number you want to reverse is curr_number;
2. Now, the places you want to reverse is x;
(remember to verify that x must be less than the number of digit of curr_number);
3. now, just take a temp integer and store curr_number / pow(10,x) ('/' = divide and pow(10,x) is 10 to the power x)
4. now, take a second number temp2, which will store curr_number-(temp * pow(10,x) )
5. reverse this temp2 (using your function)
6. now, answer = (temp * pow(10,x) ) + (temp2) //(note temp2 is reversed)
example with steps:
curr_number = 1234567
places you want to reverse is 3
temp = 1234567 / (10^3) i.e (1234567/1000) = 1234 (because it is int type)
temp2 = 1234567 - (1234*10^3) i.e 1234567 - 1234000 = 567
reverse(567) = 765
answer = (1234 * 10^3) + 765 = 1234765
Create two variables
lastn which stores the last n digits (345)
r which stores the reversed last n digits (543)
Subtract lastn from the original number (12345 - 345 = 12000)
Add r to the above number (12000 + 543 = 12543)
int c = 0; // count number of digits
int original = x;
int lastn = 0;
while (x != 0 && c < n) {
r = r * 10;
r = r + x % 10;
lastn += (x % 10) * pow(10, c);
x = x / 10;
c++;
}
printf("reversed: %d\n", original - lastn + r);
In case you don't have problems using char, you can do this
#include <stdio.h>
#include <string.h>
#define SIZE 10
int main() {
char n[SIZE]; // the Number;
int x; // number of last digits of n to reverse
int len; // number of digits of n
scanf("%s%d", n, &x);
len = strlen(n);
for(int i = 0; i < len; i++) {
i < len - x ? printf("%c", n[i]) : printf("%c", n[2*len -1 - i - x]);
}
return 0;
}
If you want you can make the program more readable by splitting the for in two
for(int i = 0; i < len - x; i++) {
printf("%c", n[i]);
}
for(int i = len-1; i >= len - x; i--) {
printf("%c", n[i]);
}
Note: the program won't work if n > x (i.e. if you want to swap more digits than you got)
I wrote this code to find the prime factorization of a number. I just cannot figure out the last part. If x is entered as a double or float, the program should print an error message and terminate. How do I achieve this?
#include <stdio.h>
int main()
{
int x, i;
printf("Enter an integer: ");
scanf("%d", &x);
if (x <= 1)
{
return 1;
}
printf("The prime factorization of %d is ", x);
if (x > 1)
{
while (x % 2 == 0)
{
printf("2 ");
x = x / 2;
}
for (i = 3; i < 1009; i = i + 2)
{
while (x % i == 0)
{
printf("%d ", i);
x = x / i;
}
}
}
return 0;
}
Your starting point should cover all desired and undesired cases so you should take float number from a user, not int. Then, you should check whether whole decimal part of the number is 0. That is, if all of them equals 0, the user want to provide an int number instead of float.
First step is to declare a float number:
float y;
After, take its value from the user:
scanf("%f", &y);
Second step is to check whether it is int or float. There are many ways for this step. For example, I find roundf() function useful. It takes a float number and computes the nearest integer to this number. So if the nearest integer is the number itself then the number has to be int. Right?
if(roundf(y)!=y)
If you are sure it is an int, you can move onto the third step: convert float type to int type. It is called type-casting. This step is required for the remaining part of your program because in your algorithm you manipulate the number with int type so just convert it to int:
x = (int)y;
After adding the line above, you can use the rest of code which you typed. I give the whole program:
#include <stdio.h>
#include <math.h>
int main()
{
int x,i;
float y;
printf("Enter an integer: ");
scanf("%f", &y);
if(roundf(y)!=y){
printf("%f is not an integer!",y);
return 1;
}
else{
x = (int)y;
}
if (x <= 1)
{
printf("%d <= 1",x);
return 1;
}
else
{
printf("The prime factorization of %d is ", x);
while (x%2 == 0)
{
printf("2 ");
x = x / 2;
}
for ( i = 3; i < 1009; i = i + 2)
{
while (x%i == 0)
{
printf("%d ",i);
x = x / i;
}
}
}
return 0;
}
The use of scanf() is a bit tricky, I would avoid it to scan user generated input at almost all cost. But nevertheless here is a short overview for how to get the errors of scanf()
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main(void)
{
int x, i, scanf_return;
printf("Enter an integer: ");
/* Reset "errno". Not necessary here, just in case. */
errno = 0;
/* scanf() returns a value in case of an error */
scanf_return = scanf("%d", &x);
/*
* scanf() returns "EOF" if it didn't find all what you wanted or
* and error happened.
* It sets "errno" to the value of the actual error. See manpage
* for all of the details.
*/
if (scanf_return == EOF) {
/*
* The error is connected to the stream, so we can differ between
* an error within scanf() and and error with the input stream
* (here: stdin)
*/
if (ferror(stdin)) {
fprintf(stderr, "Something went wrong while reading stdin: %s\n", strerror(errno));
exit(EXIT_FAILURE);
} else {
/* e.g. a conversion error, a float instead of an integer, letters
instead of a decimal number */
fprintf(stderr, "Something went wrong within scanf()\n");
exit(EXIT_FAILURE);
}
}
/*
* If no error occurred, the return holds the number of objects
* scanf() was able to read. We only need one, but it would throw an
* error if cannot find any objects, so the check is here for
* pedagogical reasons only.
*/
if (scanf_return != 1) {
fprintf(stderr, "Something went wrong within scanf(): wrong number of objects read.\n");
exit(EXIT_FAILURE);
}
if (x <= 1) {
fprintf(stderr, "Input must be larger than 1!\n");
exit(EXIT_FAILURE);
}
printf("The prime factorization of %d is ", x);
/* No need for that test, x is already larger than one at this point. */
/* if (x > 1) { */
while (x%2 == 0) {
printf("2 ");
x = x / 2;
}
for (i = 3; i < 1009; i = i + 2) {
while (x%i == 0) {
printf("%d ",i);
x = x / i;
}
}
/* } */
/* Make it pretty. */
putchar('\n');
exit(EXIT_SUCCESS);
}
Does it work?
$ ./stackoverflow_003
Enter an integer: 1234
The prime factorization of 1234 is 2 617
$ factor 1234
1234: 2 617
$ ./stackoverflow_003
Enter an integer: asd
Something went wrong within scanf(): wrong number of objects read.
$ ./stackoverflow_003
Enter an integer: 123.123
The prime factorization of 123 is 3 41
No, it does not work. Why not? If you ask scanf() to scan an integer it grabs all consecutive decimal digits (0-9) until there is no one left. The little qualifier "consecutive" is most likely the source of your problem: a floating point number with a fractional part has a decimal point and that is the point where scanf() assumes that the integer you wanted ended. Check:
$ ./stackoverflow_003
Enter an integer: .123
Something went wrong within scanf(): wrong number of objects read
How do you find out? #weather-vane gave one of many ways to do so: check if the next character after the integer is a period (or another decimal separator of your choice):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int main(void)
{
int x, i, scanf_return;
char c = -1;
printf("Enter an integer: ");
/* Reset "errno". Not necessary here, just in case. */
errno = 0;
/* scanf() returns a value in case of an error */
scanf_return = scanf("%d%c", &x, &c);
/*
* scanf() returns "EOF" if it didn't find all what you wanted or
* and error happened.
* It sets "errno" to the value of the actual error. See manpage
* for all of the details.
*/
if (scanf_return == EOF) {
/*
* The error is connected to the stream, so we can differ between
* an error within scanf() and and error with the input stream
* (here: stdin)
*/
if (ferror(stdin)) {
fprintf(stderr, "Something went wrong while reading stdin: %s\n", strerror(errno));
exit(EXIT_FAILURE);
} else {
/* e.g. a conversion error, a float instead of an integer, letters
instead of a decimal number */
fprintf(stderr, "Something went wrong within scanf()\n");
exit(EXIT_FAILURE);
}
}
/*
* If no error occurred, the return holds the number of objects
* scanf() was able to read. We can use this information now.
* If there is a period (actually any character) after the integer
* it returns 2 (assuming no error happened, of course)
*/
/* If no integer given, the following character ("%c") gets ignored. */
if (scanf_return == 0) {
fprintf(stderr, "Something went wrong within scanf(): no objects read.\n");
exit(EXIT_FAILURE);
}
/* Found two objects, check second one which is the character. */
if (scanf_return == 2) {
if (c == '.') {
fprintf(stderr, "Floating point numbers are not allowed.\n");
exit(EXIT_FAILURE);
}
}
if (x <= 1) {
fprintf(stderr, "Input must be larger than 1!\n");
exit(EXIT_FAILURE);
}
printf("The prime factorization of %d is ", x);
/* No need for that test, x is already larger than one at this point. */
/* if (x > 1) { */
while (x%2 == 0) {
printf("2 ");
x = x / 2;
}
for (i = 3; i < 1009; i = i + 2) {
while (x%i == 0) {
printf("%d ",i);
x = x / i;
}
}
/* } */
/* Make it pretty. */
putchar('\n');
exit(EXIT_SUCCESS);
}
Check:
$ ./stackoverflow_003
Enter an integer: 123
The prime factorization of 123 is 3 41
$ ./stackoverflow_003
Enter an integer: 123.123
Floating point numbers are not allowed.
$ ./stackoverflow_003
Enter an integer: .123
Something went wrong within scanf(): no objects read.
Looks good enough for me. With one little bug:
$ ./stackoverflow_003
Enter an integer: 123.
Floating point numbers are not allowed
But I think I can leave that as an exercise for the dear reader.
You can try this simple C99 implementation of Pollard Rho algorithm :
// Integer factorization in C language.
// Decompose a composite number into a product of smaller integers.
unsigned long long pollard_rho(const unsigned long long N) {
// Require : N is a composite number, not a square.
// Ensure : you already performed trial division up to 23.
// Option : change the timeout, change the rand function.
static const int timeout = 18;
static unsigned long long rand_val = 2994439072U;
rand_val = (rand_val * 1025416097U + 286824428U) % 4294967291LLU;
unsigned long long gcd = 1, a, b, c, i = 0, j = 1, x = 1, y = 1 + rand_val % (N - 1);
for (; gcd == 1; ++i) {
if (i == j) {
if (j >> timeout)
break;
j <<= 1;
x = y; // "x" takes the previous value of "y" when "i" is a power of 2.
}
a = y, b = y; // computes y = f(y)
for (y = 0; a; a & 1 ? b >= N - y ? y -= N : 0, y += b : 0, a >>= 1, (c = b) >= N - b ? c -= N : 0, b += c);
y = (1 + y) % N; // function f performed f(y) = (y * y + 1) % N
for (a = y > x ? y - x : x - y, b = N; (a %= b) && (b %= a););
gcd = a | b; // the GCD(abs(y - x), N) was computed
// it continues until "gcd" is a non-trivial factor of N.
}
return gcd;
}
Usually you performed some trial division before calling the algorithm
The algorithm isn't designed to receive a prime number as input
Two consecutive calls may not result in the same answer
Alternately, there is a pure C quadratic sieve which factors numbers from 0 to 300-bit.
If in doubt about the primality of N you can use a C99 primality checker :
typedef unsigned long long int ulong;
ulong mul_mod(ulong a, ulong b, const ulong mod) {
ulong res = 0, c; // return (a * b) % mod, avoiding overflow errors while doing modular multiplication.
for (b %= mod; a; a & 1 ? b >= mod - res ? res -= mod : 0, res += b : 0, a >>= 1, (c = b) >= mod - b ? c -= mod : 0, b += c);
return res % mod;
}
ulong pow_mod(ulong n, ulong exp, const ulong mod) {
ulong res = 1; // return (n ^ exp) % mod
for (n %= mod; exp; exp & 1 ? res = mul_mod(res, n, mod) : 0, n = mul_mod(n, n, mod), exp >>= 1);
return res;
}
int is_prime(ulong N) {
// Perform a Miller-Rabin test, it should be a deterministic version.
const ulong n_primes = 9, primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
for (ulong i = 0; i < n_primes; ++i)
if (N % primes[i] == 0) return N == primes[i];
if (N < primes[n_primes - 1]) return 0;
int primality = 1, a = 0;
ulong b;
for (b = N - 1; ~b & 1; b >>= 1, ++a);
for (ulong i = 0; i < n_primes && primality; ++i) {
ulong c = pow_mod(primes[i], b, N);
if (c != 1) {
for (int j = a; j-- && (primality = c + 1 != N);)
c = mul_mod(c, c, N);
primality = !primality;
}
}
return primality;
}
To try it there is a factor function :
// return the number that was multiplied by itself to reach N.
ulong square_root(const ulong num) {
ulong res = 0, rem = num, a, b;
for (a = 1LLU << 62 ; a; a >>= 2) {
b = res + a;
res >>= 1;
if (rem >= b)
rem -= b, res += a;
}
return res;
}
ulong factor(ulong num){
const ulong root = square_root(num);
if (root * root == num) return root ;
const ulong n_primes = 9, primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23};
for (ulong i = 0; i < n_primes && primes[i] <= root; ++i)
if (num % primes[i] == 0) return primes[i];
if (is_prime(num))
return 1 ;
return pollard_rho(num);
}
Which is completed by the main function :
#include <assert.h>
int main(void){
for(ulong i = 2; i < 63; ++i){
ulong f = factor(i);
assert(f <= 1 || f >= i ? is_prime(i) : i % f == 0);
ulong j = (1LLU << i) - 1 ;
f = factor(j);
assert(f <= 1 || f >= j ? is_prime(j) : j % f == 0);
j = 1 | pow_mod((ulong) &main, i, -5);
f = factor(j);
assert(f <= 1 || f >= j ? is_prime(j) : j % f == 0);
}
}
There are some problems in your code:
you do not check the return value of scanf, so you cannot detect invalid or missing input and will have undefined behavior in those cases.
you only test divisors up to 1009, so composite numbers with larger prime factors do not produce any output.
prime numbers larger than 1009 do not produce any output.
you should probably output a newline after the factors.
Testing and reporting invalid input such as floating point numbers can be done more easily by reading the input as a full line and parsing it with strtol().
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
char input[120];
char ch;
char *p;
long x, i;
int last_errno;
printf("Enter an integer: ");
if (!fgets(input, sizeof input, stdin)) {
fprintf(stderr, "missing input\n");
return 1;
}
errno = 0;
x = strtol(input, &p, 0);
last_errno = errno;
if (p == input || sscanf(p, " %c", &ch) == 1) {
fprintf(stderr, "invalid input: %s", input);
return 1;
}
if (last_errno == ERANGE) {
fprintf(stderr, "number too large: %s", input);
return 1;
}
if (x < 0) {
fprintf(stderr, "number is negative: %ld\n", x);
return 1;
}
if (x <= 1) {
return 1;
}
printf("The prime factorization of %ld is", x);
while (x % 2 == 0) {
printf(" 2");
x = x / 2;
}
for (i = 3; x / i >= i;) {
if (x % i == 0) {
printf(" %ld", i);
x = x / i;
} else {
i = i + 2;
}
}
if (x > 1) {
printf(" %ld", x);
}
printf("\n");
return 0;
}
Here is my attempt at computing the GCD of two input numbers:
int rep;
do{
system ("cls");
int a, b, gcd=2, e, d;
cin >> a >> b;
if(a % b != 0 || b % a != 0){
do{
gcd = gcd + 1;
d = a % gcd;
e = b % gcd;
} while(d==0 && e==0);
cout << gcd-1;
}else if(a == 1 || b == 1){
gcd=1;
cout << gcd;
}else if(a >= b){
gcd = a;
cout << gcd;
}else if(b >= a){
gcd = b;
cout << gcd;
}
cin >> rep;
} while(rep == 1);
If I input 8 and 24, it gives me 2 as the answer. Can anyone spot the problem in my code?
The problem is that the algorithm gives up the first time a test GCD fails. In most cases, finding the greatest means going past some values that do not work. In this case, working up to 8 means getting past 3, 5 and 7.
8 % 24 == 8. So the do loop runs at least once. gcd becomes 3 and is tested, but does not divide evenly into 8, so the while condition evaluates to false. Then 3 - 1 (2) is streamed to cout. It's not the correct GCD, though.
You could revise your algorithm to start with the lesser of the 2 inputs, and work downward until there is a success (8 here), and then a failure (7 here).
The meat of the GCD algorithm here is only 3 lines, the rest is devoted to preventing silliness.
#include <stdio.h>
unsigned GCD(unsigned x, unsigned y) {
unsigned z;
if (x < y) {
z = x; // swap
x = y;
y = z;
}
if (y == 0)
return 0;
while (z = x % y) { // perform the GCD with implicit 0 test
x = y;
y = z;
}
return y;
}
int main(void)
{
printf("GCD of %u, %u = %u\n", 1, 0, GCD(1, 0)); // billed as C
printf("GCD of %u, %u = %u\n", 0, 1, GCD(0, 1));
printf("GCD of %u, %u = %u\n", 1, 1, GCD(1, 1));
printf("GCD of %u, %u = %u\n", 8, 24, GCD(8, 24));
return 0;
}
Program output:
GCD of 1, 0 = 0
GCD of 0, 1 = 0
GCD of 1, 1 = 1
GCD of 8, 24 = 8
For my programming class we are making a main() function that calls multiple other functions. Two of these functions are numberStats() and triad(), both of which have their own variables, no global variables are used, and numberStats() is called immediately before triad(). Neither codes have similar variable names, but for some reason when I use the triad function, which asks the user to input 3 ints, it spits out the first int correctly but the 2nd and 3rd ints are the two ints inputted into the numberStats() function. Can anyone explain why this is happening and what I might be able to do to fix it? Thank you in advance, new blood here.
EDIT*
here's the output code: (if it's italicized then it's the numbers I entered in as input)
numberStats: Please enter two positive ints: 5 800 //I input 5 and 800
800 is larger
5 is smaller
800 + 5 = 805
800 - 5 = 795
800 * 5 = 4000
800 % 5 = 0
triad: Please enter three positive ints:
1 2 3 //I input 1 2 and 3
you entered 1, 5, and 800
Not all equal
Sorted order: 1, 5, 800
I obviously did not enter 1, 5, and 800 for the triad function, why would it tell me I did?
EDIT** Source code for numberStats() and triad():
void numberStats(void)
{
int var1, var2, a, b, c, d;
printf("numberStats: Please enter two positive ints: ");
scanf("%d %d",&var1, &var2);
if (var1 > var2){
printf("%d is larger\n",var1);
printf("%d is smaller\n",var2);
a = var1 + var2;
b = var1 - var2;
c = var1 * var2;
d = var1 % var2;
printf("%d + %d = %d\n",var1,var2,a);
printf("%d - %d = %d\n",var1,var2,b);
printf("%d * %d = %d\n",var1,var2,c);
printf("%d %% %d = %d\n",var1,var2,d);
}
else if (var1 < var2){
printf("\n%d is larger\n",var2);
printf("%d is smaller\n",var1);
a = var2 + var1;
b = var2 - var1;
c = var2 * var1;
d = var2 % var1;
printf("%d + %d = %d\n",var2,var1,a);
printf("%d - %d = %d\n",var2,var1,b);
printf("%d * %d = %d\n",var2,var1,c);
printf("%d %% %d = %d\n",var2,var1,d);
}
else if (var1 == var2){
printf("%d and %d are the same\n",var1,var2);
a = var1 + var2;
b = var1 - var2;
c = var1 * var2;
d = var1 % var2;
printf("%d + %d = %d\n",var1,var2,a);
printf("%d - %d = %d\n",var1,var2,b);
printf("%d * %d = %d\n",var1,var2,c);
printf("%d %% %d = %d\n",var1,var2,d);
}
}
void triad(void)
{
int x, y, z, low, mid, high;
printf("\ntriad: Please enter three positive ints: \n");
scanf("%d, %d, %d", &x, &y, &z);
printf("you entered %d, %d, and %d\n", x, y, z);
if (x == y && y == z){
printf("All equal\n");
}
if (x <= y && x <= z){
low = x;
if (y <= z){
mid = y;
high = z;
}
else{
mid = z;
high = y;
}
printf("Not all equal\n");
}
if (x >= y && x >= z){
high = x;
if (y <= z){
low = y;
mid = z;
}
else{
low = z;
mid = y;
}
printf("Not all equal\n");
}
if ((x >= y && x <= z) || (x <= y && x >= z)){
mid = x;
if (y >= z){
high = y;
low = z;
}
else{
high = z;
low = y;
}
printf("Not all equal\n");
}
printf("Sorted order: %d, %d, %d\n", low, mid, high);
}
The functions triad() and scanf() are causing the trouble:
int x, y, z, low, mid, high;
printf("\ntriad: Please enter three positive ints: \n");
scanf("%d, %d, %d", &x, &y, &z);
You're looking for commas in the data, but not entering them (you gave "1 2 3" but you needed to give "1,2,3" with commas (and optional spaces) separating the numbers). scanf() returned 1 instead of 3, but you ignored it. Don't! Check your inputs, every time.
As a result, you have quasi-random values in y and z, which is why you're running into problems.
A basic debugging technique is to print the values just read:
if (scanf("%d, %d, %d", &x, &y, &z) != 3)
…report error and bail out…
printf("x = %d, y = %d, z = %d\n", x, y, z);
I am trying to write a program to perform point operations on a elliptic curve in a prime field I am using the standard formulaes for point additions and doubling in my code and these operations are performed by functions that are called but I am getting output for certain points but not all so please help me to fix the problem that are present in this code.
structure point_multiply(int x, int y, int k )
{
int xk;
int yk,m;
xk=x;
yk=y;
m=1;
int xL,yL,s,e;
e=findInverse((2*yk),211);
if((((3*(xk*xk))*e)% 211)>0)
{s = (((3*(xk*xk))*e)% 211);
}
else
s=(((3*(xk*xk))*e)% 211)+ 211;
if((((s*s)- (2*xk)) % 211)>0)
{xL=(((s*s)- (2*xk)) % 211);
}
else
xL=(((s*s)- (2*xk)) % 211) + 211;
if(((-yk+ s*(xk-xL)) % 211) > 0)
yL=(-yk+ s*(xk-xL)) % 211;
else
yL=(-yk+ s*(xk-xL)) % 211 + 211;
xk=xL;
yk=yL;
m=m+1;
while(k>m)
{
sn=point_addition(xk,yk,x,y);
xk=sn.a;
yk=sn.b;
m++;
}
s1.a=xk;
s1.b=yk;
return s1;
}
structure point_addition(int x1, int y1, int x2, int y2)
{
int s,xL,yL;
if((x1-x2)!=0)
{
if ( x1 == 0 && y1 == 0 )
{
xL = x2;
yL = y2;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( x2 == 0 && y2 == 0 )
{
xL = x1;
yL = y1;
s7.a=xL;
s7.b=yL;
return s7;
}
if ( y1 == -y2 )
{
xL = yL = 0;
s7.a=xL;
s7.b=yL;
return s7;
}
l=findInverse((x1-x2),211);
if ((((y1-y2)*l) % 211)>=0)
s=((((y1-y2)*l) % 211));
else
s=(((y1-y2)*l) % 211) + 211;
if ((((s*s)-(x1+x2)) % 211)>0)
xL= (((s*s)-(x1+x2)) % 211) ;
else
xL= (((s*s)-(x1+x2)) % 211) + 211;
if(((-y1+s*(x1-xL)))>=0)
yL= ((-y1+s*(x1-xL)) % 211);
else
yL= ((-y1+s*(x1-xL)) % 211) + 211;
}
else
{
xL= 0 ;
yL= 0;
}
s7.a= xL;
s7.b= yL;
return s7 ;
}
int findInverse(int a, int b)
{
int x[3];
int y[3];
int quotient = a / b;
int remainder = a % b;
x[0] = 0;
y[0] = 1;
x[1] = 1;
y[1] = quotient * -1;
int i = 2;
for (; (b % (a%b)) != 0; i++)
{
a = b;
b = remainder;
quotient = a / b;
remainder = a % b;
x[i % 3] = (quotient * -1 * x[(i - 1) % 3]) + x[(i - 2) % 3];
y[i % 3] = (quotient * -1 * y[(i - 1) % 3]) + y[(i - 2) % 3];
}
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
if(x[(i - 1) % 3]<0)
return x[(i - 1) % 3]+211;
else
//x[i — 1 % 3] is inverse of a
//y[i — 1 % 3] is inverse of b
return x[(i - 1) % 3];
}
Edited and added main c code which uses these function to perform elliptic curve cryptography
int main()
{
int y,z=0,x=2,i[200],j[200],h=0,g,k;
while(x<200)
{
y=sqrt((x*x*x)-4);
z=modulo(y,211);
if(z!=0)
{
i[h]=x;
j[h]=z;
s[h].a=i[h];
s[h].b=j[h];
s[h+1].a=i[h];
s[h+1].b=(211 - j[h]);
printf("\nh=%d X= %d Y= %d \nh=%d X= %d Y= %d",h,s[h].a,s[h].b,h+1,s[h+1].a,s[h+1].b);
h=h+2;
}
x++;
}
printf("The total no of points we have on our elliptic curve for cryptography is %d",h-1);
x=5;
y=11;
printf("\n %d %d\n",x,y );
printf("\nEnter A number between 0 and the private key");
scanf("%d",&k);
s2=point_multiply(x,y,k);
printf("\n The public key is \n %d %d \n ",s2.a,s2.b );
printf("Enter a RANDOM number to generate the cipher texts");
scanf("\n%d",&g);
s3= point_multiply(x,y,g);
s4=point_multiply(s2.a,s2.b,g );
label:
printf("\n Enter a number to send");
scanf("%d",&h);
s6=point_addition(s4.a,s4.b,s[h].a,s[h].b);
printf("The points to be sent are X= %d Y=%d",s[h].a,s[h].b);
printf(" \n X= %d Y=%d\n X = %d Y= %d ",s3.a,s3.b,s6.a,s6.b);
//RECIEVER
s8=point_multiply(s3.a,s3.b,k);
s9=point_addition((s8.a) ,-((s8.b)%211),s6.a,s6.b);
printf(" The decrypted points are \n %d %d",s9.a,s9.b);
printf("\n If you have more no to send press 1 else press 0");
scanf("\n %d", &x1);
if(x1==1)
goto label;
else
return 0;
}
s1, s2, s3 etc are structures which hold a 2 integers which act as x and y co-ordinates
I am getting output by entering k=3,g=4, h=5 and many other cases mostly with small numbers but not for larger numbers. What could be wrong with the code?
Further edit: I guess that normal square root method is not applicable to find square roots of a modular no?.. Please tell me how to find the modular square root of a no?