Changing a value of an integer in a function - c

I have a problem with the function 'multiply2' which doesn't change values of ccn1 to ccn8. It has to multiply them by 2, and if the result is equal or more than 10, than take products of this equation and add them together (i.e. 7 * 2 = 14, so 1 + 4 = 5). The whole thing would work, but I've noticed that the function 'multiply2' keeps the value of pX to itself, and I'd like to overwrite values of ccn1 to ccn8, and then sum all values together (ccn1 to ccn16). Please help :(
PS: I'm new at this so please be gentle, I'm sure it looks like a mess to you.
The program compiles as it is with no errors, mind you, it does include cs50.h library for "get_long_long" function which prompts a user for a credit card number
I've tried to use pointers but clearly I don't fully understand the concept! I've managed to dereference *pX which assigned values of ccn1, ccn2, etc. but they still don't update in main.
the whole problem described here: https://docs.cs50.net/2018/x/psets/1/credit/credit.html#tl-dr
Thank you!
# include <cs50.h>
# include <stdio.h>
# include <math.h>
void multiply2 (int * pX);
long long ccn;
//a program to check the credit card number and print out if it's American Express, Visa, or MasterCard. if else - ILVALID.
int main(void)
{
//prompt user for a credit card number
ccn = get_long_long("Number: ");
//every second digit starting from second to last
int ccn1 = (ccn % 100) / 10;
int ccn2 = (ccn % 10000) / 1000;
int ccn3 = (ccn % 1000000) / 100000;
int ccn4 = (ccn % 100000000) / 10000000;
int ccn5 = (ccn % 10000000000) / 1000000000;
int ccn6 = (ccn % 1000000000000) / 100000000000;
int ccn7 = (ccn % 100000000000000) / 10000000000000;
int ccn8 = (ccn % 10000000000000000) / 1000000000000000;
//printf("%i\n%i\n%i\n%i\n%i\n%i\n%i\n%i\n", ccn1, ccn2, ccn3, ccn4, ccn5, ccn6, ccn7, ccn8);
//all the other digits
int ccn9 = (ccn % 10);
int ccn10 = (ccn % 1000) / 100;
int ccn11 = (ccn % 100000) / 10000;
int ccn12 = (ccn % 10000000) / 1000000;
int ccn13 = (ccn % 1000000000) / 100000000;
int ccn14 = (ccn % 100000000000) / 10000000000;
int ccn15 = (ccn % 10000000000000) / 1000000000000;
int ccn16 = (ccn % 1000000000000000) / 100000000000000;
//printf("%i\n%i\n%i\n%i\n%i\n%i\n%i\n%i\n", ccn9, ccn10, ccn11, ccn12, ccn13, ccn14, ccn15, ccn16);
if (((ccn >= 340000000000000 && ccn <= 349999999999999) || (ccn >= 370000000000000 && ccn <= 379999999999999)) ||
((ccn >= 5100000000000000 && ccn <= 5199999999999999) || (ccn >= 5500000000000000 && ccn <= 5599999999999999)) ||
((ccn >= 4000000000000 && ccn <= 4999999999999) || (ccn >= 4000000000000000 && ccn <= 4999999999999999)))
{
multiply2(&ccn1);
multiply2(&ccn2);
multiply2(&ccn3);
multiply2(&ccn4);
multiply2(&ccn5);
multiply2(&ccn6);
multiply2(&ccn7);
multiply2(&ccn8);
int sum = (ccn1 + ccn2 + ccn3 + ccn4 + ccn5 + ccn6 + ccn7 + ccn8 + ccn9 + ccn10 + ccn11 + ccn12 + ccn13 + ccn14 + ccn16);
printf("%i\n", sum);
}
/NOTHING FROM ABOVE - INVALID
else
{
printf("INVALID\n");
}
}
void multiply2 (int * pX)
{
if ((*pX *2) >= 10)
{
*pX = ((*pX * 2) % 10) + 1;
printf("%i\n", *pX);
}
else
{
printf("%i\n", (*pX * 2));
}
}

Your function multiply2 changes the value of the passed parameter only in case its value is at least 5.
Try this:
void multiply2(int* pX)
{
*pX = *pX * 2; /* Multiply value by 2 */
if (*pX >= 10)
*pX = (*pX % 10) + 1; /* Adjust if value greater than or equal to 10 */
printf("%d\n", *pX);
}

Related

Validating credit cards

I'm very new to C language much less programming in general and am working through the cs50 edx course. I encountered this problem in week 1 where I'm supposed to validate credit cards given their characteristics (they're in the comments).
After hours worth of research and trials, I managed to solve it though I think it's way too long and I am 90% sure it can be shortened with loops. I added the long version that works and an iteration of it which uses loops that I just can't get to work. Any advice would help and be very much appreciated!
#include <stdio.h>
#include <cs50.h>
int main(void)
{
//user input for credit card number
long creditCard = get_long("Credit Card: ");
//initialize array for finding digits
int digit[16];
int oddDigits[8];
//separate all digits as variables in array digits[]
digit[0] = ((creditCard / 1000000000000000) % 10);
digit[1] = ((creditCard / 100000000000000) % 10);
digit[2] = ((creditCard / 10000000000000) % 10);
digit[3] = ((creditCard / 1000000000000) % 10);
digit[4] = ((creditCard / 100000000000) % 10);
digit[5] = ((creditCard / 10000000000) % 10);
digit[6] = ((creditCard / 1000000000) % 10);
digit[7] = ((creditCard / 100000000) % 10);
digit[8] = ((creditCard / 10000000) % 10);
digit[9] = ((creditCard / 1000000) % 10);
digit[10] = ((creditCard / 100000) % 10);
digit[11] = ((creditCard / 10000) % 10);
digit[12] = ((creditCard / 1000) % 10);
digit[13] = ((creditCard / 100) % 10);
digit[14] = ((creditCard / 10) % 10);
digit[15] = (creditCard % 10);
//double the value of every other digit as oddDigits[]
oddDigits[0] = digit[0] * 2;
oddDigits[1] = digit[2] * 2;
oddDigits[2] = digit[4] * 2;
oddDigits[3] = digit[6] * 2;
oddDigits[4] = digit[8] * 2;
oddDigits[5] = digit[10] * 2;
oddDigits[6] = digit[12] * 2;
oddDigits[7] = digit[14] * 2;
//the first part in finding the sum of every other digit
for (int o = 0; o < 8; o++) {
if (oddDigits[o] > 9) {
oddDigits[o] -= 9;
}
}
//part 2 of finding the sum of every other digit
int sum = 0;
for (int s = 0; s < 8; s++) {
sum += oddDigits[s];
}
//sum of everything else
for (int s2 = 1; s2 < 16; s2 += 2) {
sum += digit[s2];
}
//check if last digit is 0
int check = sum % 10;
//last part of validation
if (check != 0)
printf("INVALID\n");
//type of card
else {
if (digit[0] == 0 && digit[1] == 3 && (digit[2] == 4 || digit[2] == 7)) //15 digits starting with either 34 or 37
{
printf("AMAX\n");
}
else if (digit[0] == 5 && (digit[1] == 1 || digit[1] == 2 || digit[1] == 3 || digit[1] == 4 || digit[1] == 5)) //16 digits starting with either 51 - 54
{
printf("MASTERCARD\n");
}
else if (digit[0] == 4) //16 digits starting with 4
{
printf("VISA\n");
}
else if (digit[0] == 0 && digit[1] == 0 && digit[2] == 0 && digit[3] == 4) //13 digits starting with 4
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
}
The only part I changed is where I try to get every digit of the number using for loops and the part where I try to double every other digit... I did a test where after the loop it will print all the digits separately and it always prints 1 no matter what and I'm wondering what I'm doing wrong here...
//initialize array for finding digits
int digit[16];
int oddDigits[8];
//separate all digits as variables in array digits[]
for (int d = 0; d < 16; d++) {
for (long i = 1000000000000000; i > 9; i /= 10) {
digit[d] = ((creditCard / i) % 10);
}
}
//double the value of every other digit as oddDigits[]
for (int n = 0; n < 8; n++) {
for (int t = 0; t < 15; t += 2) {
oddDigits[n] = digit[t]*2;
}
}
While you are separating all digits as variables in array digits[], the for loop runs till.
digit[14] = ((creditCard / 10) % 10);
to fix this change it as
for (long i = 1000000000000000; i > 0; i /= 10)
{
digit[d] = ((creditCard / i) % 10);
}
ie change 9 to 0. in this way, the last iteration of the loop will run
digit[15] = ((creditCard/1) % 10);
which is same as
digit[15] = (creditCard % 10);
now see, the outer loop is running 16 times. the inner loop is also running 16 times and the inner loop is running only once per iteration of the outer loop. So one of the loops is redundant. remove the outer loop. keep the d variable as 0 and increment it by 1 after dividing the digit. i.e.
int d = 0;
//separate all digits as variables in array digits[]
for (long i = 1000000000000000; i > 9; i /= 10)
{
digit[d] = ((creditCard / i) % 10);
d++;
}
You can also do it like this
long i = 1000000000000000;
for (int d = 0; d < 16; d++)
{
digit[d] = ((creditCard / i) % 10);
i /= 10;
}
Either one will work.
Now this part //double the value of every other digit as oddDigits[]
It can also be done with 1 loop. In your code, the variable t is just double of the variable n in each step. So, you don't need the t variable too. (just replace t by 2*n)
//double the value of every other digit as oddDigits[]
for (int n = 0; n < 8; n++)
{
oddDigits[n] = digit[2*n]*2;
}

sum-digits function - C language

Digits Sum function
I have to write a function - digits sum,
for ex.: the number : 9887, 9+8+8+7= 32 , 3+2= 5
Will this function work well?
int sum_digits(int num){
if (num < 10)
return num;
int a = sum_digits (num / 10) + num % 10;
if (a > 9)
a = sum_digits (a / 10) + a % 10;
return a;
}
int sum_digits(int num){
if (num < 10)
return num;
int a = sum_digits (num / 10) + num % 10;
if (a > 10)
a += sum_digits (a / 10) + a % 10;
return a;
}
This will work.
Note that a= is replaced by a+= and a>9 is replaced by a>10

C program not displaying value

when i call my multi() it will calculate the binary number just fine, but won't calculate the adding(). If i switch the two in order, it will calculate the adding() and not calculate the multi(). Is there a reason why the second function call isn't displaying its value? It will print the printf, but not the value. Any help would be great.
#include <stdio.h>
long binary1, binary2, binary3, binary4, multiply = 0;
int binaryproduct(int, int);
int digit, factor = 1;
int multi();
int adding();
int main()
{
binary3 = binary1;
binary4 = binary1;
printf("Enter the first binary number: ");
scanf("%ld", &binary1);
printf("Enter the second binary number: ");
scanf("%ld", &binary2);
multi();
printf("\n");
adding();
}
int adding()
{
int i = 0, remainder = 0, sum[20];
while (binary3 != 0 || binary4 != 0) {
sum[i++] =(binary3 % 10 + binary4 % 10 + remainder) % 2;
remainder =(binary3 % 10 + binary4 % 10 + remainder) / 2;
binary1 = binary3 / 10;
binary2 = binary4 / 10;
}
if (remainder != 0) {
sum[i++] = remainder;
}
--i;
printf("Sum of two binary numbers: ");
while (i >= 0) {
printf("%d", sum[i--]);
}
return 0;
}
int multi()
{
while (binary2 != 0) {
digit = binary2 % 10;
if (digit == 1) {
binary1 = binary1 * factor;
multiply = binaryproduct(binary1, multiply);
} else {
binary1 = binary1 * factor;
}
binary2 = binary2 / 10;
factor = 10;
}
printf("Product of two binary numbers: %ld", multiply);
return 0;
}
int binaryproduct(int binary3, int binary4)
{
int i = 0, remainder = 0, sum[20];
int binaryprod = 0;
while (binary1 != 0 || binary2 != 0) {
sum[i++] =(binary1 % 10 + binary2 % 10 + remainder) % 2;
remainder =(binary1 % 10 + binary2 % 10 + remainder) / 2;
binary1 = binary1 / 10;
binary2 = binary2 / 10;
}
if (remainder != 0) {
sum[i++] = remainder;
}
--i;
while (i >= 0) {
binaryprod = binaryprod * 10 + sum[i--];
}
return binaryprod;
}
Your globals aren't being initialized. In you adding() function you use:
binary1 = binary3/10
binary2 = binary4/10
and in the binaryproduct function you have two local ints named binary3, binary4 that you don't use.
You should be using unique names, initializing you variables, use local variables in places where globals are unnecessary.

Numbers acting strange in both Lua and C

I have written this program in Lua and C which is a greedy algorithm.
Greedy = function(num)
local q = 0;
local d = 0;
local n = 0;
local p = 0;
local x = 1;
while x == 1 do
if (num >= 0.25) then
q = q + 1;
num = num - 0.25;
print("q");
elseif (num >= 0.10) then
d = d + 1;
num = num - 0.10;
print("d");
elseif (num >= 0.05) then
n = n + 1;
num = num - 0.05;
print("n");
elseif (num >= 0.01) then
p = p + 1;
num = num - 0.01;
print("p");
end
if (num == 0) then
x = 0;
end
end
if (x == 0) then
local all = q+d+n+p;
print(all);
end
end
Greedy(1);
This code works fine with some numbers but if I try to calculate numbers like 0.90,0.04 or 0.12 it wont work and I have the same code written in C too. But I have the same problem with it.
#include <stdio.h>
int greedy(void){
int quarter = 0;
int dime = 0;
int nickel = 0;
int penny = 0;
float num = 0.40;
int x = 1;
while(x == 1){
if (num >= 0.25){
quarter = quarter + 1;
num = num - 0.25;
printf("q\n");
}else if(num >= 0.10){
dime = dime + 1;
num = num - 0.10;
printf("d\n");
}else if(num >= 0.05){
nickel = nickel + 1;
num = num - 0.05;
printf("n\n");
}else if(num >= 0.01){
penny = penny + 1;
num = num - 0.01;
printf("p\n");
};
if(num == 0){
x = 0;
};
};
if(x == 0){
int all = quarter + dime + nickel + penny;
printf("%i\n", all);
};
return 0;
};
int main(void){
greedy();
}
What did I do wrong?
The problem is that, many floating-point numbers can't be represented (using double or float) precisely, try this in Lua:
> print(0.9 == 0.9 - 0.2 + 0.1 + 0.1)
false
It should be equal in maths, but not here. The same for the C code.
Seeing your scope is counting your money, rewrite your code this way:
Greedy = function(num)
local q = 0;
local d = 0;
local n = 0;
local p = 0;
local x = 1;
num=num*100
while x == 1 do
if (num >= 25) then
q = q + 1;
num = num - 25;
print("q");
elseif (num >= 10) then
d = d + 1;
num = num - 10;
print("d");
elseif (num >= 5) then
n = n + 1;
num = num - 5;
print("n");
elseif (num >= 1) then
p = p + 1;
num = num - 1;
print("p");
end
if (num == 0) then
x = 0;
end
end
if (x == 0) then
local all = q+d+n+p;
print(all);
end
end
Greedy(1);

C Array behaves different with different number of digits, why?

I have a code that gets a number from input and then puts it into array, and then prints said array. But there is very strange side-effect, when I enter 13 digit number, my last digit is wrong. If I enter 15 or 16 digit number everything is fine. I can't understand what's happening! Here is the code:
numberDigits is either 12, 14 or 15, based on the number of digits in number.
int myNumber[numberDigits];
for (int i = 0; i <= numberDigits; i++)
{
myNumber[numberDigits - i] = number % 10;
number = number / 10;
}
printf("\n");
for (int i = 0; i <= numberDigits; i++)
{
printf("%i",myNumber[i]);
}
EDIT:
My number is initialized as long long int. Here is a check to verify number of digits:
if (number / 1000000000000 >= 1 && number / 1000000000000 < 10)
{
numberDigits = 12;
}
if (number / 100000000000000 >= 1 && number / 100000000000000 < 10)
{
numberDigits = 14;
}
if (number / 1000000000000000 >= 1 && number / 1000000000000000 < 10)
{
numberDigits = 15;
}
EDIT: Last update, Yes, I have updated my code and it works as expected with your suggestions, but I need to understand why my code doesn't work. I think that maybe array[12] actually holds 12 elements and not 13, and when I access element array[12] with it, I get some random value from memory, but why this doesn't happen with array[14] or array[15] with 15 and 16 digit numbers respectively. And why program does not crash as it should when you access array at wrong position. Original question below with old code that doesn't work.
EDIT: Here is whole listing for those interested.
#include <stdio.h>
#include <cs50.h>
int verify (long long int number);
int main(void)
{
printf("Please enter card number: \n");
long long int number = GetLongLong();
// AMEX uses 15 digits
if (number > 100000000000000 && ((number / 10000000000000 == 34) || (number / 10000000000000 == 37)))
{
printf("AMEX");
}
if (number > 1000000000000 && number < 10000000000000 && (number / 1000000000000 == 4))
{
printf("VISA");
}
if (number > 1000000000000000 && number < 9999999999999999 && (number / 1000000000000000 == 4))
{
printf("VISA");
}
if (number > 1000000000000000 && number < 9999999999999999 && (number / 100000000000000 == 51 || number / 100000000000000 == 52 || number / 100000000000000 == 53 || number / 100000000000000 == 54 || number / 100000000000000 == 55))
{
printf("MASTERCARD");
}
return verify(number);
}
int verify (long long int number)
{
int numberDigits;
if (number / 1000000000000 >= 1 && number / 1000000000000 < 10)
{
numberDigits = 12;
}
if (number / 100000000000000 >= 1 && number / 100000000000000 < 10)
{
numberDigits = 14;
}
if (number / 1000000000000000 >= 1 && number / 1000000000000000 < 10)
{
numberDigits = 15;
}
int myNumber[numberDigits];
for (int i = 0; i <= numberDigits; i++)
{
myNumber[numberDigits - i] = number % 10;
number = number / 10;
}
printf("\n");
for (int i = 0; i <= numberDigits; i++)
{
printf("%i",myNumber[i]);
}
return 0;
}
Your for loop should look like this:
for (int i = 0; i < numberDigits; i++)
Since indexes are zero-based, the last one will be numberDigits - 1. And so <= would go past the end.
I think it should be something like this:
for(int i = 0; i < numberDigits; ++i) printf("%d",myNumber[i]);
instead of:
for(int i = 0; i <= numberDigits; ++i) printf("%i",myNumber[i]);
And in the first loop:
myNumber[numberDigits - (i + 1)] = number % 10;
Also, you could use something like this to know the number of digits:
int digits(long long num) {
if(!num) return 1;
return log10(num) + 1;
}

Resources