The nth term of the series is f(n).
f(n) = 1, when n=1
f(n)= ((n-1)*(8*(n–2)* 2+ 20)+4) , when n>1
P(n)=f(1)+f(2)+.....f(n)
1<=n<=10^9
for a given n we have to find P(n) modulo 10^9+7.
I solved the equation and finally getting the answer as
P(n)=(16n^3-18n^2+14n-12)/3
Problem comes when I implemented it in c++.
Given below the code tell me whats wrong with it and how to resolve it?
#include<stdio.h>
#define c 1000000007
int main()
{
long long int t,n,sum;
scanf("%lld",&t);
while(t--)
{
sum=0;
scanf("%lld",&n);
if(n==1)
printf("1\n");
else
{
sum=(((16*(((((n%c)*(n%c))%c)*(n%c))%c)%c)+14*(n%c))%c-(18*(((n%c)*(n%c))%c)%c+12)%c)/3;
sum++;
printf("%lld\n",sum);
}
}
return 0;
}
There are multiple issues in your code.
Problem 1:
An expression like long long b = ((a%c)*(a%c))%c; with a and b being long long
and c just a "plain number", ie. int, is still subject to int overflow, without
using the full capabilities of long long. The reason is the result of modulo:
long long = ((long long % int) * (long long % int)) % int;
long long = (int * int) % int;
long long = int % int; //overflow here
long long = int;
long long = long long; //expanding too late
//finished
As an example to check (http://ideone.com/kIyM7K):
#include <iostream>
using namespace std;
int main() {
int i = 1000000;
long long ll = 1000000;
cout<< ((999999%i)*(999999%i)*(999999%i)) << endl;
cout<< ((999999%ll)*(999999%ll)*(999999%ll)) << endl;
return 0;
}
In your code, 1000000007 is not a long long ...
Use 1000000007ULL to treat is as unsigned long long
Problem 2:
You´re using (or at least "used", before the edits) %lld in printf and scanf
for unsigned long long, which is %llu. %lld would be a signed long long
Problem 3:
P(n) purely mathematical and without modulo is positive for every natural number n>=1.
But P(0) is negative, and more important: The four parts of your equation modul´t
and the added/subtracted together could result in a negative number, which is congruent
to the positive expected result, but C doesn´t know that.
So, use signed instead of unsigned, and after the whole calculation, check
if the result is <0 and add c to it to make it >0
Problem 4:
A problem with parenthesis and operator precedence somewhere in your long formula.
A working example, but without the loops and input:
#include<stdio.h>
int main()
{
signed long long n, res, c;
n = 2456ULL;
c = 1000000007ULL;
signed long long part1 = (16*(((n%c)*(n%c)%c)*(n%c)%c))%c;
signed long long part2 = (18*((n%c)*(n%c)%c))%c;
signed long long part3 = (14*(n%c))%c;
res = ((part1 - part2 + part3 - 12)%c)/3 + 1;
printf("%lld\n", res);
return 0;
}
Not a problem:
You don´t need a special check for n=1, because the
whole calculation will result in 1 anyways.
Related
Sorry for this weird question but I'm only a beginner. I created a program with two while loops next to each other. The first while loop takes user input and repeats until input=0. When the second while loop begins, it takes the input = 0 from the first while loop. How to run the second while loop with original user input? Thank you.
unsigned long long int inp,inp1,rem,rem1,ans=0,ans1=0,place_value=1,place_value1=1;
printf("Please input binary for conversion:\n");
scanf("%llu", &input);
inp=input;
while (input>0){
rem=input%10;
ans=ans+rem*place_value;
input=input/10;
place_value=place_value*2;
}
while (input!=0){
rem1 = inp1 % 10;
ans1 = ans1 + rem * place_value1;
place_value1 = place_value1* 2;
inp1 = inp1 / 10;
}
printf("%d in Binary is %llu in Decimal Form.\n\n", inp,ans);
printf("%d in Binary is %d in Octal Form.\n", inp1,ans1);
printf("");
I finally found a fix without functions. Thank you to everyone for helping me. Declaring another variable was indeed the fix, I just needed to refine it a bit more.
else if(op=='B' || op=='b'){
unsigned long long int inp,rem=0,ans=0,place_value=1;
printf("You have chosen Binary to Decimal and Octal\n");
printf("Please input binary for conversion:\n");
scanf("%llu", &input);
inp=input;
while (input>0){
rem=input%10;
ans=ans+rem*place_value;
input=input/10;
place_value=place_value*2;
}
unsigned long long int rem1=0,ans1=0,place_value1=1;
input1=inp;
while (input1!=0){
rem1 = input1 % 10;
ans1 = ans1 + rem1 * place_value1;
place_value1 = place_value1 * 2;
input1 = input1 / 10;
}
printf("%llu in Binary is %llu in Decimal Form.\n\n", inp,ans);
printf("%llu in Binary is %o in Octal Form.\n", inp,ans1);
main();
}
You have way too many variables in your code. And similar names which only differ by some appended number is a mess. And you are mixing it all up. For instance you never assign a value to inp1 and you use input where it should have been inp1. You use rem where it should be rem1. It's too complicated... It's time to use functions...
unsigned long long int foo(unsigned long long int input)
{
unsigned long long int rem;
unsigned long long int ans=0;
unsigned long long int place_value=1;
while (input>0){
rem = input % 10;
ans = ans + rem * place_value;
input = input / 10;
place_value = place_value * 2;
}
return ans;
}
unsigned long long int bar(unsigned long long int input)
{
unsigned long long int rem;
unsigned long long int ans=0;
unsigned long long int place_value=1;
while (input!=0){
rem = input % 10;
ans = ans + rem * place_value;
place_value = place_value * 2;
input = input / 10;
}
return ans;
}
and then use the functions like
unsigned long long int input, ans_foo, ans_bar;
printf("Please input binary for conversion:\n");
scanf("%llu", &input);
ans_foo = foo(input);
ans_bar = bar(input);
printf("%d in Binary is %llu in Decimal Form.\n\n", input, ans_foo);
printf("%d in Binary is %d in Octal Form.\n", input, ans_bar);
printf("");
Note To me it seems that your two while loops are doing the same... but that's an unrelated mistake.
The easiest solution would be to define a new variable to store the input value.
unsigned long long int value = input
But I think this problem would be easier to resolve/read with recursion.
Here you have a working example.
My code for finding 10th decimal digit of square root of 2.
#include <stdio.h>
unsigned long long int power(int a, int b);
unsigned long long int root(int a);
int main()
{
int n;
n=10;
printf("%llu \n",root(n));
return 0;
}
unsigned long long int power(int a, int b)
{
int i;
unsigned long long int m=1;
for (i=1;i<=b;i++)
{
m*=a;
}
return m;
}
unsigned long long int root(int a)
{
unsigned long long int c=1;
int counter=1;
while(counter<=a)
{
c*=10;
while(power(c,2)<=2*power(10,2*counter))
{
c++;
}
c-=1;
counter++;
}
return c;
}
I have tried the same algorithm in python. It can find the 10th decimal digit of $sqrt{2}$ immediately.
However, while doing C, I have waited for 10 mins but without a result.
Python handles big numbers for you. [1]
Although, as you say that you are getting the answer "immediately", your algorithm in python is not probably the same as the one you used in C.
#bruno's answer already explains why you are not getting the expected results in C.
[1] Handling very large numbers in Python
Exceed the range that the data can represent. when counter is equal to 10,2*power(10,2*counter) exceeds the range that unsigned long long int can represent. Python supports large number calculations, unlimited digits
you have overflow(s)
when counter values 10 you try to compute power(10,20) but even long long on 64 bits are not enough large, so you loop in
while(power(c,2)<=2*power(10,2*counter)){
c++;
}
for a long time (may be without ending)
Having long long on 64 bits allows to compute the result for n valuing up to 9
I am writing a very basic program to print the range of an unsigned long long variable in C language (0 to ((2 ^ n) - 1) where n is the number of bits for the data type in any system (with C installed in it and according to the compiler). In my system, the size of a long long variable is 8 bytes.
I am using the following code:
#include<stdio.h>
#include<math.h>
int main()
{
unsigned long long n;
//n = pow(2, 63);
//n = (n * 2) - 1;
n = pow(2, 64) - 1;
printf("\nn: %llu\n", n);
return 0;
}
upon compiling, gcc gives me the following error:
Print_long_long_int.c:10:2: warning: overflow in implicit constant conversion [-Woverflow].
On executing it, I get the correct output of
n: 18446744073709551615
But, if I remove the single comments from the lines, and use them:
n = pow(2, 63);
n = (n * 2) - 1;
Instead of:
n = pow(2, 64) - 1;
It doesn't give me any such warning. And executes normally.
Why is this discrepancy happening?
Thanks!
When you are giving
pow(2,64) -1 ;
It exceeds the limit of unsigned long long. This is the reason you are getting that warning.
Range of unsigned long is 0 to 18,446,744,073,709,551,615
Result of pow(2,64) is 18446744073709551616.
Power should return an integer, and you're getting an unsigned long long. I just made a simple power function to handle unsigned long longs.
#include<stdio.h>
unsigned long long power(int base, int exponent)
{
unsigned long long n = 1;
int i;
for (i = 0; i < exponent ; i++)
n *= base;
return n;
}
int main()
{
unsigned long long n = power(2, 64) - 1;
printf("n: %llu\n", n);
return 0;
}
I'm writing C code that converts from an integer to its binary representation, reverses the binary and then converts back to an integer. It's working well, but I need it to work for input values up to 10^9. Right now, it seems to break for anything larger than 10^7. What I mean is I put in a number such as 10000000 and get out 17967657062982931584 as being the binary representation (despite being accurate for smaller integers). In addition, I am not sure where my int_to_binary is the only function experiencing this problem, or if the others need to be optimized for large inputs as well. Any ideas where I'm going wrong? Thank you.
#include <stdio.h>
#include <string.h>
unsigned long long int_to_binary(unsigned long long k) {
if (k == 0) return 0;
if (k == 1) return 1;
return (k % 2) + 10 * int_to_binary(k/2);
}
unsigned long long reverse_int(unsigned long long l) {
unsigned long long reversed;
reversed = 0;
while (l > 0) {
reversed = reversed * 10 + (l%10);
l = l / 10;
}
return reversed;
}
unsigned long long binary_to_int(unsigned long long k) {
char binaryString[80];
snprintf(binaryString, 4, "%llu", k);
unsigned long long decimal = 0;
int length = strlen(binaryString);
int i = 0;
while(i < length) {
decimal = (decimal << 1) + (binaryString[i] - 0x30);
i++;
}
return decimal;
}
int main() {
int number;
printf("Enter a number: ");
scanf("%d", &number);
printf("You entered %d\n", number);
unsigned long long b = int_to_binary(number);
printf("In Binary, this is %llu\n", b);
unsigned long long c = reverse_int(b);
printf("When we reverse it, it looks like this: %llu\n", c);
unsigned long long d = binary_to_int(c);
printf("And when we convert that back to an int, it looks like this: %llu\n", d);
return 0;
}
You're using long long to represent a binary number as a decimal. On many architectures this results in the maximum value being stored of 2**64-1 = 18446744073709551615.
If you put in a decimal number such as 10000000, it cannot be represented as a decimal-binary number in 64 bits.
The problem is attempting to manipulate a binary number as a sum of powers of ten. It's more efficient to manipulate binary directly. Just change 10 to 2 in the reverse_int function.
unsigned long long reverse_int(unsigned long long l) {
unsigned long long reversed;
reversed = 0;
while (l > 0) {
reversed = reversed * 2 + (l%2);
l = l / 2;
}
return reversed;
}
In order to print numbers in binary, write a loop, testing each bit in sequence, using modulo % or bitwise operators like & and >>.
why should a code like this should provide a so high result when I give it the number 4293974227 (or higher)
int main (int argc, char *argv[])
{
unsigned long long int i;
unsigned long long int z = atoi(argv[1]);
unsigned long long int tmp1 = z;
unsigned long long int *numbers = malloc (sizeof (unsigned long long int) * 1000);
for (i=0; tmp1<=tmp1+1000; i++, tmp1++) {
numbers[i] = tmp1;
printf("\n%llu - %llu", numbers[i], tmp1);
}
}
Result should start with the provided number but starts like this:
18446744073708558547 - 18446744073708558547
18446744073708558548 - 18446744073708558548
18446744073708558549 - 18446744073708558549
18446744073708558550 - 18446744073708558550
18446744073708558551 - 18446744073708558551
ecc...
What's this crap??
Thanks!
atoi() returns int. If you need larger numbers, try strtol(), strtoll(), or their relatives.
atoi() returns (int), and can't deal with (long long). Try atoll(), or failing that atol() (the former is preferred).
You are printing signed integers as unsigned.