Incorrect calculations of averages - c

I have this super simple code for calculating averages of given even and odd numbers, until the user gives 0. (I would use for loop but we can't).
I'm having a really strange problem with program rounding results like 25/2 is 2.00000. Sorry if this question is stupid but I just can't find a problem.
What am I doing completely wrong?
#include <stdio.h>
#include <stdlib.h>
void funkcja()
{
int sumaNiep = 0;
int sumaPa = 0;
int userInput = 1;
int i = 0;
while(userInput != 0)
{
//wprow zmiennej
printf("%d. Podaj calkowita liczbe: ", i+1);
scanf("%d", &userInput);
//jesli parzysta
if (userInput % 2 == 0)
{
sumaPa += userInput;
} else {
sumaNiep += userInput;
}
i++;
}
double sredniaNiep = sumaNiep/(i-1);
double sredniaPa = sumaPa/(i-1);
printf("\nsrednia parzysta %d / %d : %lf", sumaPa, i, sredniaPa);
printf("\nsrednia parzysta %d / %d : %lf", sumaNiep, i, sredniaNiep);
}
int main()
{
funkcja();
}

The problem is that you do an integer division at the end.
You should break out of the loop if the user enters 0 and make at least one operand a double when you do the division. You also need to count the number of evens and odds:
#include <stdio.h>
#include <stdlib.h>
void funkcja() {
int sumaNiep = 0;
int sumaPa = 0;
int userInput = 1;
int iPa = 0;
int iNiep = 0;
int i = 0;
while(1) {
printf("%d. Podaj calkowita liczbe: ", ++i);
if(scanf(" %d", &userInput) != 1 || userInput == 0) break; // break out
// jesli parzysta
if(userInput % 2 == 0) {
sumaPa += userInput;
++iPa; // count evens
} else {
sumaNiep += userInput;
++iNiep; // count odds
}
}
if(iPa) { // avoid div by zero
double sredniaPa = (double)sumaPa / iPa; // double div
printf("srednia parzysta %d / %d : %lf\n", sumaPa, iPa, sredniaPa);
}
if(iNiep) { // avoid div by zero
double sredniaNiep = (double)sumaNiep / iNiep; // double div
printf("srednia parzysta %d / %d : %lf\n", sumaNiep, iNiep, sredniaNiep);
}
}

The problem was I divided by the number of all digits (odd and even) to calculate both averages. Here is improved code:
#include <stdio.h>
#include <stdlib.h>
void funkcja()
{
int sumaNiep = 0;
int sumaPa = 0;
int userInput = 1;
int i_p = 0, i_np = 0;
while(userInput != 0)
{
//wprow zmiennej
printf("%d. Podaj calkowita liczbe: ", i_p+i_np+1);
scanf("%d", &userInput);
//jesli parzysta
if (userInput % 2 == 0)
{
sumaPa += userInput;
if (userInput != 0)
{
i_p++;
}
} else {
sumaNiep += userInput;
i_np++;
}
}
if (i_np != 0)
{
double sredniaNiep = sumaNiep/(i_np);
printf("\nSrednia nieparzysta %d / %d : %lf", sumaNiep, i_np, sredniaNiep);
}
if (i_p != 0)
{
double sredniaPa = sumaPa/(i_p);
printf("\nSrednia parzysta %d / %d : %lf", sumaPa, i_p, sredniaPa);
}
}
int main()
{
funkcja();
}

Related

Checking whether space should be printed in the middle or at the end in for loop?

I am trying to give info to my program whether it should print space or not.
My code looks something like this, and its printing spaces at the end (which is not what I want)
void function(int given_limit)
{
int current_num = 2;
while (given_limit > 1)
{
if (given_limit % current_num == 0)
{
if (current_num == 2)
{
printf("%d ", current_num);
}
else if (current_num == 3)
{
printf("%d ", current_num);
}
else if (current_num == 5)
{
printf("%d ", current_num);
}
else if (current_num == 7)
{
printf("%d ", current_num);
}
else
{
printf("%d ", current_num);
}
given_limit /= current_num;
}
else
current_num++;
}
printf("\n");
}
In main() I am calling it something like this:
int main()
{
int given_limit = 13;
for (int i = 0; i <= given_limit; i++)
{
printf("%d\t\t", i);
function(i);
}
}
I would appreciate any tips and help.
One of the ideas is maybe to store it in an array.
I replaced spaces with asterisks for better visibility and removed the redundant if-elements. Then I introduced a flag which indicates whether it is the output of the first factor or a later one. In front of each later one we put the space (or asterisk).
#include <stdio.h>
#include <stdbool.h>
void function(int given_limit)
{
bool is_first_factor = true;
int current_num = 2;
while (given_limit > 1)
{
if (given_limit % current_num == 0)
{
if (is_first_factor) {
is_first_factor = false; // not first anymore
// print nothing
} else {
printf("*"); // between two factors
}
printf("%d", current_num);
given_limit /= current_num;
}
else
current_num++;
}
printf("\n");
}
int main(int argc, char **argv)
{
int given_limit = 13;
for (int i = 0; i <= given_limit; i++)
{
printf("%d\t\t", i);
function(i);
}
}
$ gcc spacing.c
$ ./a.out
0
1
2 2
3 3
4 2*2
5 5
6 2*3
7 7
8 2*2*2
9 3*3
10 2*5
11 11
12 2*2*3
13 13
$
As mentioned above move the space character to in front of each prime factor and then align the output to take the initial starting space character into account.
This example also skips unnecessary factors.
/* primefactors.c
*/
#include <stdio.h>
void primeFactors(int number)
{
printf(" %2d ", number);
// only test factors <= sqrt(number)
// skip even factors > 2
int factor = 2;
while (factor <= number / factor) {
if (number % factor == 0) {
printf(" %d", factor);
number /= factor;
}
else if (factor == 2){
factor = 3;
}
else {
factor += 2;
}
}
// at this point number equals the greatest prime factor
printf(" %d\n", number);
}
int main (void)
{
int max = 45;
printf("\nnumber prime factors\n");
printf("------ -------------\n");
// skip 0 and 1 which have no prime factors
printf(" %2d\n", 0);
printf(" %2d\n", 1);
for (int i = 2; i <= max; ++i) {
primeFactors(i);
}
return 0;
}

Find two largest numbers in input

I need to make a program that will perform the following task:
Enter N natural numbers. Complete the input with 0. Output the number
of the maximal number.
I have already done this, and you can see the code below:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void) {
int i = 0, num, max_place = -1;
int max = -2147483647;
printf("Start enter numbers, bruh (please end input with 0):\n");
scanf("%d", &num);
while (num != 0) {
if (num >= max) {
max = num;
max_place = i;
}
i++;
scanf("%d", &num);
}
if (max_place == -1) printf("Numbers were not entered");
else printf("\nMax number was on %d place, bruh", max_place + 1);
return 0;
}
The teacher then made the task more difficult – the program needs to print the maximum number and the next maximum after it of the entered numbers.
How can I do it?
If you can use arrays and sort use that way. if not, this is in your code
int main(void) {
int i = 0, num, max_place = -1, second_max_place = -1;
int max = -2147483647;
int second_max = -2147483647;
printf("Start enter numbers, bruh (please end input with 0):\n");
scanf("%d", &num);
while (num != 0) {
if (num == 0) break;
if (num >= max) {
second_max = max;
second_max_place = max_place;
max = num;
max_place = i;
}
if(num < max && num >= second_max){
second_max = num;
second_max_place = i;
}
i++;
scanf("%d", &num);
}
if (max_place == -1) printf("Numbers were not entered");
else{
printf("\nMax number was on %d place, bruh", max_place + 1);
printf("\nSecond Max number was on %d place, bruh", second_max_place + 1);
}
return 0;
}

sum of all the digit of a number using while-loop in C

I'm trying to solve a problem (as the title already state). I've actually learned that I can do it with modulo operator (%). But the first code that I wrote is using the while-loop, so I'm trying to finish the code.
This is the code
int main()
{
char arr[1000000];
int i = 0;
int sum = 0;
printf("type the number = ");
scanf("%s", arr);
while(arr[i] != '\0'){
sum = arr[i] + sum;
i++;
}
printf("the total number is = %d", sum);
so the problem is it's actually printing out some huge amount of number.. I guess it's because of the array is in char, can someone help me how do I changed the value into int ?
You need to substract from the digit code the code of '0'.
Here you have the both versions (I have added some logic to accept the numbers with + & - at there beginning):
int sumdigitsStr(const char *num)
{
int sum = 0;
int first = 1;
while(*num)
{
if(isdigit(*num)) {sum += *num - '0'; first = 0;}
else
if(first && (*num == '-' || *num == '+'))
{
first = 0;
num++;
continue;
}
else
{
sum = -1; break;
} //error string contains non digits
num++;
}
return sum;
}
int sumdigits(long long num)
{
int sum = 0;
do
{
sum += abs((int)(num % 10));
}while((num = num / 10));
return sum;
}
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n);
int d, sum = 0;
while (n != 0)
{
d = n % 10;
sum = sum + d;
n = n / 10;
}
printf("sum of digits is : %d", sum);
return 0;
}

I can not determine if it is a prime number

The below program correctly outputs the divisors of the input numbers, but it does not correctly report whether the inputs are prime. For example, when the input is 13, it does not print "The number you entered is a prime number." What's wrong with it?
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num;
bool isPrime = true;
printf("Enter a number: ");
while (scanf("%d", &num) == 1)
{
for (int i = 2; i * i <= num; ++i)
{
if (num % i == 0)
{
if (i * i != num)
{
printf("%d ve %d, divides %d\n", i, num / i, num);
}
else
{
printf("%d divides %d.\n", i, num);
}
isPrime = false;
}
}
}
if (isPrime)
{
printf("The number you entered is a prime number.");
}
return 0;
}
the reason is that scanf is in a while loop if there's a valid input but you are checking & printing if it's prime outside of the loop... if you expect this program just get one input and validate it once, then you just need to change that while to if:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num;
bool isPrime = true;
printf("Enter a number: ");
if (scanf("%d", &num) == 1)
{
for (int i = 2; i * i <= num; ++i)
{
if (num % i == 0)
{
if (i * i != num)
{
printf("%d ve %d, divides %d\n", i, num / i, num);
}
else
{
printf("%d divides %d.\n", i, num);
}
isPrime = false;
}
}
}
if (isPrime)
{
printf("The number you entered is a prime number.");
}
return 0;
}
If you expect this program goes in a loop to keep on getting input and validating if it's prime or not, this should do the job:
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num;
bool isPrime = true;
while (1)
{
isPrime=true;
printf("Enter a number: ");
if (scanf("%d", &num) == 1)
{
for (int i = 2; i * i <= num; ++i)
{
if (num % i == 0)
{
if (i * i != num)
{
printf("%d ve %d, divides %d\n", i, num / i, num);
}
else
{
printf("%d divides %d.\n", i, num);
}
isPrime = false;
}
}
}
if (isPrime)
{
printf("The number you entered is a prime number.\n");
}
}
return 0;
}
You have missed 2 things !
You should have printed inside the while loop !
In addition to that you didn't change the status of isPrime=true; !
Hope this answers your question !
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int num;
bool isPrime = true;
while (scanf("%d", &num) == 1)
{
for (int i = 2; i * i <= num; ++i)
{
if (num % i == 0)
{
if (i * i != num)
{
printf("%d ve %d, divides %d\n", i, num / i, num);
}
else
{
printf("%d divides %d.\n", i, num);
}
isPrime = false;
}
}
if (isPrime)
{
printf("The number you entered is a prime number.\n");
}
isPrime=true;
}
return 0;
}
When you entered a prime number, your while loop doesn't break. Try it:
#include <stdio.h>
#include <stdbool.h>
int main(void) {
int num;
bool isPrime = true, finishIt = false;
printf("Enter a number: ");
while (1) {
while (1) {
if (scanf("%d", &num) != 1)
continue;
if (num == 0) {
finishIt = true;
break;
}
int i;
for (i = 2; i * i <= num; ++i) {
if (num % i == 0) {
if (i * i != num) {
printf("%d ve %d, divides %d\n", i, num / i, num);
} else {
printf("%d divides %d.\n", i, num);
}
isPrime = false;
}
}
if (i * i >= num)
break;
}
if (isPrime) {
printf("The number you entered is a prime number.");
}
isPrime = true;
if (finishIt)
break;
}
return 0;
}

RSA Encryption C code

I am having trouble doing my homework.
I am doing an RSA application which can encrypt and decrypt.
The problem is that after I Input things to encrypt the results are weird and I can't decrypt anything. This is because when I copied the results of encryption which are symbols, I got more weird stuffs.
I'm guessing it has something to do with my formula getting negative ASCIIs as results.
Below is what I tried, and, in order to understand what I meant by weird, just compile and try it out(I have some unused stuffs which I haven't removed yet):
Output:
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#define boolean int
#define true 1
#define false 0
//===================================================//
int p = 0;
int q = 0;
int n = 0;
int m = 0;
int divider = 2;
int tempdivider = 2;
int initial = 0;
int x = 0;
int y = 0;
char msg[100];
char alphabet[27];
//===================================================//
void cls();
void menu();
void init();
void reinit();
void inputencrypt();
//int encrypt(int num);
void encrypt();
char decrypt(char text[]);
int fpb(int num);
int d(int num);
int primecheck(int a);
boolean checkdigit(char text[]);
//===================================================//
int main() {
frontpage();
init();
menu();
getchar();
return 0;
}
//===================================================//
void cls() {
for (int i = 0;i < 25;i++) {
printf("\n");
}
}
//===================================================//
boolean checkdigit(char text[]) {
int len = strlen(text);
for (int i = 0;i < len;++i) {
if (text[i]<'0' || text[i]>'9') {
return false;
}
}
return true;
}
int primecheck(int a) {
if (a == 1) {
return false;
}
for (int i = 2;i < a;i++) {
if (a%i == 0) {
return false;
}
}
return true;
}
//===================================================//
void reinit() {
for (int i = 1;i < 27;i++) {
alphabet[i] = 'a' + i - 1;
}
p = 0;
q = 0;
n = 0;
m = 0;
divider = 2;
tempdivider = 2;
initial = 120;
x = 0;
y = 0;
}
void init() {
reinit();
do {
printf("p = ");
scanf("%d", &p);fflush(stdin);
if (!primecheck(p)) {
printf("must be prime number! \n");
}
} while (!primecheck(p));
do {
printf("q = ");
scanf("%d", &q);fflush(stdin);
if (!primecheck(q)) {
printf("must be prime number! \n");
}
} while (!primecheck(q));
n = p*q;
m = (p - 1)*(q - 1);
initial = m;
x = fpb(m);
y = d(m);
printf("n = %d\n", n);
printf("m = %d\n", m);
printf("e = %d\n", x);
printf("d = %d\n", y);
system("pause");
}
//===================================================//
void menu() {
char input[2];
int input1 = 0;
do {
do {
cls();
printf("main menu\n");
printf("================\n");
printf("1. encrypt\n");
printf("2. decrypt\n");
printf("3. exit\n");
printf(">> ");
scanf("%s", input);fflush(stdin);
if (checkdigit(input)) {
input1 = atoi(input);
}
} while (!checkdigit(input));
switch (input1) {
case 1:
int c;
char encrypted[100];
char word[100];
printf("input word to encrypt : ");
scanf(" %[^\n]", word);fflush(stdin);
for (int i = 0;i < strlen(word);i++) {
if (word[i] == ' ') {
encrypted[i] = ' ';
//i++;
}
else {
for (int j = 1;j < 27;j++) {
if (word[i] == alphabet[j]) {
c = 0;
c = pow(j, x);
c = c%n;
encrypted[i] = c;
break;
}
}
}
}
printf("\n\nWord ASCII [ ");
for (int i = 0;i < strlen(word);i++) {
//printf("%d", c);
printf("%d ", word[i]);
}
printf(" ]\n");
printf("\n\nEncrypted ASCII [ ");
for (int i = 0;i < strlen(word);i++) {
//printf("%d", c);
printf("%d ", encrypted[i]);
}
printf(" ]\n");
printf("\n\nEncrypted [ ");
for (int i = 0;i < strlen(word);i++) {
//printf("%d", c);
printf("%c", encrypted[i]);
}
printf(" ]");
printf("\n\n\n");
system("pause");
break;
case 2:
int temp[100];
char decrypted[100];
char wordx[100];
int h;
printf("input word to decrypt : ");
scanf(" %[^\n]", wordx);fflush(stdin);
for (int i = 0;i < strlen(wordx);i++) {
temp[i] = wordx[i];
//temp[i] -= 97;
//printf("%d ::: %c\n", temp[i], temp[i]);
}
for (int i = 0;i < strlen(wordx);i++) {
if (wordx[i] == ' ') {
decrypted[i] = ' ';
}
else {
h = 0;
h = pow(temp[i], y);
h = h%n;
decrypted[i] = h;
for (int j = 1;j < 27;j++) {
if (decrypted[i] == j) {
decrypted[i] = alphabet[j];
}
}
}
}
printf("\n\nWord ASCII [ ");
for (int i = 0;i < strlen(wordx);i++) {
//printf("%d", c);
printf("%d ", wordx[i]);
}
printf(" ]\n");
printf("\n\nDecrypted ASCII [ ");
for (int i = 0;i < strlen(wordx);i++) {
//printf("%d", c);
printf("%d ", decrypted[i]);
}
printf(" ]\n");
printf("\n\nDecrypted [ ");
for (int i = 0;i < strlen(wordx);i++) {
//printf("%d", decrypted[i]);
printf("%c", decrypted[i]);
}
printf(" ]");
printf("\n\n\n");
system("pause");
break;
}
} while (input1 != 3);
}
//===================================================//
int fpb(int num) {
if (!primecheck(num)) {
if (num%divider == 0) {
num = num / divider;
divider = 2;
}
else {
divider++;
}
fpb(num);
}
else if (primecheck(num)) {
if (!primecheck(num + divider)) {
tempdivider++;
divider = tempdivider;
num = initial;
fpb(num);
}
else {
return num + divider;
}
}
}
int d(int num) {
for (int i = 1;i < num;i++) {
if ((x*i) % num == 1) {
return i;
}
}
}
You have a general comprehension problem. Your console is only able to represent 96 characters correctly (known as printable 7bit-ASCII characters, 0x20 to 0x7F), but a byte can hold 255 different values. Your encryption algorithm does not care about this limited range, it will encrypt any value in the range [0..255] into another value in the range [0..255]. So your ASCII input characters will most likely be encrypted into values that cannot be represented by your console correctly. Copy&Past will not work correctly for non-printable characters (like 0x0B, which is a tab).
But now you will wonder: Why does that work for e.g. E-Mails? Simply: Because those characters are converted into an ASCII representation. Please google a bit for Base64 encoding.
As an alternative, you can always stream your encrypted characters into a file and later read back from that. This way you will bypass the limitations of your console.
Btw: Please have a look at the documentation of printf() and you will know, why you get those negative values.
The encrypt option has these three statements consecutively
c = 0;
c = pow(j, x);
c = c%n;
and the last of those will leave c in the range 0..(n-1).
Apart from that, there is no else clause and int c; can remain uninitialised.
So all in all it is inevitable that when you print c values as characters you will get "weird" results.
As for negative values, char encrypted[100]; is probably signed char so any integer value in the range 128..255 assigned to that, although undefined behaviour, may possibly show up as a negative number because the signed char is promoted back to int when passed as format %d to printf.

Resources