How to take modulus of a large value stored in array? - c

Suppose I have a integer array containing digits and I want to take modulus of value stored in it, i.e
int a[36]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9}
and convert it into a number like 987654321987654321987654321987654321.
In C language long long int permits only 10^18. I want to take modulus with 10^9+7. How can i do that?
Program:
int main()
{
int a[36]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9};
long long int temp=0;
int i;
for(i=0;i<36;i++)
{
temp=temp+a[i]*pow(10,i);
}
temp=temp%1000000007;
printf("%lld",temp);
return 0;
}

Since 36 decimal digits is too much for a typical long long, you need to perform your modulus operation during the conversion:
int a[36]={1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9,1,2,3,4,5,6,7,8,9};
long long int temp=0;
for(int i=35 ; i >= 0 ; i--) {
temp = 10*temp + a[i];
temp %= 1000000007;
}
printf("%lld",temp);
I made two changes to your code:
Fixed the way you convert an array of digits to a number - your code used pow, and treated digits at higher indexes as higher-order digits. This creates precision problems once you get past the highest power of ten that can be represented as double.
Moved the %= into the loop - your code does not let the number overflow by keeping the value in the range from 0 to 1000000006, inclusive.
Running this code produces the same value that you would obtain with a library that supports arbitrary precision of integers (I used Java BigInteger here).

Related

How can I get a very large number to get printed a digit (its remainder) at a time? (a credit card validation code)

I'm working on a code to verify valid credit card numbers. I'll be using the Luhn algorithm logic eventually, But first I'm trying to store the single digits of the card number into an array of size 20. Since there is no way to split an integer (integer here is the credit card number) I thought of getting the remainder of the integer by dividing by 10 (This way I can get the individual digits). However, my problem is that when the size of the integer becomes 11 or more, only a few digits are getting stored and with the wrong values. I just started to learn C programming and would really appreciate it if someone could help me, Thank you.
Note: I have given -1 to the 0th index of the array to say that it's the end of the card number.
eg: 123467321234-1
Code :
#include <stdio.h>
int main() {
long int cardNo[20];
long int input_cardNo;
int cardNo[0] = -1; //card number ends here
int i = 1;
printf("Enter your card number : ");
scanf("%d", &input_cardNo);
do {
long int remainder = input_cardNo % 10; //getting the remainder of card number
long int division = input_cardNo / 10; //getting the div value of card number
cardNo[i] = remainder; //assigning the remainder value to an [i] index in the array
printf("%d\n", cardNo[i]);
input_cardNo = division; //updating the card number with the div vale
i++;
} while (input_cardNo != 0);
return 0;
}
Just a brief explanation why long int does not work.
For most operating systems long int stores have the same capacity as int, it stores from -2^31 to 2^31 - 1. See: Long Vs. Int C/C++ - What's The Point?
With this, the maximum value is: 2147483648 or around 9-10 digits for your case. You may use long long int to store up to 4.611686e+18 or 17-18 digits.

Calculating sum of digits of 2^n in C

I am new to C and trying to write a program that calculates the sum of the digits of 2^n, where n<10^8.
For example, for 2^10, we'd have 1+0+2+4, which is 7.
Here's what I came up with:
#include <stdio.h>
#include <math.h>
int main()
{
int n, t, sum = 0, remainder;
printf("Enter an integer\n");
scanf("%d", &n);
t = pow(2, n);
while (t != 0)
{
remainder = t % 10;
sum = sum + remainder;
t = t / 10;
}
printf("Sum of digits of 2 to the power of %d = %d\n", n, sum);
return 0;
}
The problem is: the program works fine with numbers smaller than 30. Once I set n to a number higher than 30, the result is always -47.
I really do not understand this error and what causes it.
An interesting problem to be sure, but I think the solution is way outside the scope of a simple answer if you wish to support large values of n, such as the 108 you mentioned. The number 2108 requires 108 + 1 (100,000,001) bits, or around 12 megabytes of memory, to store in binary. In decimal it has around 30 million digits.
Your int is 32 bits wide, which is why the signed int can't store 231 – the 32nd bit is the sign while 231 has a 1 followed by 31 zeros in binary, requiring 32 bits without the sign. So it overflows and is interpreted as a negative number. (Technically signed integer overflow is undefined behaviour in C.)
You can switch to an unsigned int to get rid of the sign and the undefined behaviour, in which case your new highest supported n will be 31. You almost certainly have 64-bit integers available, and perhaps even 128-bit, but 2127 is still way less than 2100000000.
So either you need to find an algorithm to compute the decimal digits of a power of 2 without actually storing them (and only store the sum), or forget about trying to use any scalar types in standard C and get (or implement) an arbitrary precision math library operating on arrays (of bits, decimal digits, or binary-coded decimal digits). Alternatively, you can limit your solution to, say, uint64_t, but then you have n < 64, which is not nearly as interesting… =)
For signed int t = pow(2,n), if n >= 31 then t > INT_MAX.
You can use unsigned long long t = pow(2,n) instead.
This will allow you to go as up as n == 63.
Also, since you're using base 2, you can use (unsigned long long)1 << n instead of pow(2,n).

How to find out in C whether a double number has any digits after decimal point

I stumbled on one issue while I was implementing in C the given algorithm:
int getNumberOfAllFactors(int number) {
int counter = 0;
double sqrt_num = sqrt(number);
for (int i = 1; i <= sqrt_num; i++) {
if ( number % i == 0) {
counter = counter + 2;
}
}
if (number == sqrt_num * sqrt_num)
counter--;
return counter;
}
– the reason for second condition – is to make a correction for perfect squares (i.e. 36 = 6 * 6), however it does not avoid situations (false positives) like this one:
sqrt(91) = 18.027756377319946
18.027756377319946 * 18.027756377319946 = 91.0
So my questions are: how to avoid it and what is the best way in C language to figure out whether a double number has any digits after decimal point? Should I cast square root values from double to integers?
In your case, you could test it like this:
if (sqrt_num == (int)sqrt_num)
You should probably use the modf() family of functions:
#include <math.h>
double modf(double value, double *iptr);
The modf functions break the argument value into integral and fractional parts, each of
which has the same type and sign as the argument. They store the integral part (in
floating-point format) in the object pointed to by iptr.
This is more reliable than trying to use direct conversions to int because an int is typically a 32-bit number and a double can usually store far larger integer values (up to 53 bits worth) so you can run into errors unnecessarily. If you decide you must use a conversion to int and are working with double values, at least use long long for the conversion rather than int.
(The other members of the family are modff() which handles float and modfl() which handles long double.)

Adding Big Ints from Array in C Results in No Output

I am new to C (and programming in general, minus a few weeks with Python). I am interested in learning how information is handled on a machine level, therefore I moved to C. Currently, I am working through some simple coding challenges and am having trouble finding information to resolve my current issue.
The challenge is to take N large integers into an array from input and print the sum of the numbers. The transition from Python to C has actually been more difficult than I expected due to the simplified nature of Python code.
Example input for the code below:
5
1000000001 1000000002 1000000003 1000000004 1000000005
Expected output:
5000000015
Code:
int main() {
long long unsigned int sum = 0;
int nums[200], n, i;
scanf("%i", &n);
for (i = 0; i =! n; i++) {
scanf("%i", &nums[i]);
sum = sum + nums[i];
}
printf("%llu", sum);
return 0;
}
The program seems to accept input for N, but it stops there.
One last question, in simple terms, what is the difference between a signed and unsigned variable?
Change your for loop like this
for (i = 0; i != n; i++) {
scanf("%i", &nums[i]);
sum = sum + nums[i];
}
if you say i =! n that is the same as i = !n. What that does is to assign the negated value of n to i. Since you gave a non-zero value to n the result is zero and the loop terminates.
Welcome to C!
Regarding the signed vs unsigned question. signed types can have negative values and unsigned can't. But they both take up the same space (number of bits) in memory. For instance, assuming twos' complement representation and a 32 bit integer, the range of values is
singed : -2^31 to 2^31 - 1 or –2147483648 to 2147483647
unsigned : 0 to 2^32 - 1 or 0 to 4294967295

This program doesn't work properly for decimals more than 10 digits?

The below code is used to count number of digit in a given decimal. The problem is that it doesn't count digits more than 10.
int NumDigits(int n) {
int digits = 0;
if (n <= 0) {
n = -n;
++digits;
}
while (n) {
n /= 10;
++digits;
}
return digits;
}
It seems like your toolchain has a 32-bit int type. The maximum value representable in such a type is 231-1, or 2,147,483,647. As you can see, that's a 10-digit number. You'll need to use a different type that supports larger numbers if you want to use this kind of an algorithm.
That's a 32 bit integer, which has a maximum amount of 2,147,483,647. You might want to look into using 64 bit integers or other solutions.
Try long for the argument type.
As Jonathan already stated in his comment an int cannot contain a number with more than 10 digits.
The reason is that your parameter is of the type int, which is limited in size.
Most likely you have Int32 (you can find it out with sizeof(int) which gives you the size in byte) which goes up to 2147483647 and then overflows to the negative value -2147483648.
Example:
int i = 2147483647;
i = i+1;
printf("%d\n",i);
gives you the output: "-2147483648"

Resources