C++ program to calculate the sum of all five-digit odd numbers? - c++

I'm having a problem with the following simple code, I don't know why the output will become negative... The program is supposed to calculate the sum of all odd and five-digit numbers like 10001, 10003, 10005, etc.
#include <iostream>
using namespace std;
int main()
{
int num, sum = 0;
for (num = 10001 ; num <= 99999 ; num+=2){
sum += num;
}
cout << num << " " << sum;
return 0;
}

It means that there is an overflow of type int. That is this type can not represent the sum. I advice to declare variable sum like
long long int sum = 0;
After that you can compare the result with the maximum value stored in type int. For example
#include <limits>
//...
std::cout << std::numeric_limits<int>::max() << " " << sum << std::endl;;

Your int will likely overflow. Switch it to long
int num = 0;
long long sum = 0L;
Assuming you have a 4 byte int, the maximum value will be 2^31 - 1 == 2147483647. See this example
Your sum will come out to 2475000000 which will overflow.

Related

Why can't I set my long long variable to 1e18 + 10?

I have implemented a program in C++ and it showed a very strange bug.
First of all, if I assigned my variable a like this: long long a = 1e9 + 10 and then print the value of a, it ran correctly. But if I set a to 1e18 + 10 and then print the value of a, it showed that a equals 10^18 only. Can anyone help me with this? I tried a lot but I can't understand why. Thanks.
This is my code:
#include <iostream>
using namespace std;
int main() {
long long a = 1e9 + 10;
cout << a << endl;
a = 1e18 + 10;
cout << a << endl;
return 0;
}
1e18 is a value having type double. The presicion of type double is typically around 15 decimal digits, so adding 10 to 1e18 may not change the value of double.
You can add a cast to long long before addition to eliminate the issue in this case, but generally you should avoid using floating-point numbers to deal with integers.
#include <iostream>
int main(void) {
long long value = static_cast<long long>(1e18) + 10;
std::cout << value << '\n';
return 0;
}

Unusal behaviour of sum in C++?

I'm writing a method to check if a number is palindrome or not. For example 12321 is palindrome and 98765 is not.
In my program I've used a recursive function to create exactly opposite of given number, like 56789 for 98765 and then checking if two numbers are equal or not. But I'm not getting exact opposite of 98765 which is 56789 instead I'm getting 56787.
Here's my code-
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
long int oppositeNum(int n){
if(n<10 && n>=0) return n;
if(n<0) return 0;
static int m=0;
int x = n%10;
long int num = oppositeNum(n/10);
cout << num << "\n";
return (num+ (x*pow(10,++m)));
}
int main(){
int n = 98765;
int oppNum = oppositeNum(n);
cout << oppNum;
if(oppNum==n){
cout << "Number is palindrome";
}else{
cout << "Number is not palindrome";
}
return 0;
}
I'm not getting the exact opposite of my original nnumber. the last digit is getting decremented by 1 every time is what I've observed.
Can anyone help?
I can not reproduce the result you are getting. Maybe it is a consequence of using the function pow
But in any case your function may not be called the second time for a different number because the static variable m is not reinitialized to 0. m continues to keep the value after the previous call of the function for a different number.
You can write the function without using the function pow.
Take into account that a reversed number can be too large to be stored an object of the type long because in some systems the type long has the same width as the type int. So I adjust instead of the type long to use the type long long as the return type.
Here you are.
#include <iostream>
long long int oppositeNum( int n )
{
static long long int multiplier = 1;
const int Base = 10;
int digit = n % Base;
return ( n /= Base ) == 0
? ( multiplier = 1, digit )
: ( n = oppositeNum( n ) , multiplier *= Base, digit * multiplier + n );
}
int main()
{
int n = 12321;
std::cout << n << " -> " << oppositeNum( n ) << '\n';
n = - 12321;
std::cout << n << " -> " << oppositeNum( n ) << '\n';
n = 98765;
std::cout << n << " -> " << oppositeNum( n ) << '\n';
n = -98765;
std::cout << n << " -> " << oppositeNum( n ) << '\n';
return 0;
}
The program output is
12321 -> 12321
-12321 -> -12321
98765 -> 56789
-98765 -> -56789
I changed only as much as it seemed neccessary. It still could use some tail recursion but this would probably required rewriting the whole algorithm.
long int oppositeNum(int n, int &m){
if(n<10) return n;
int x = n%10;
long int num = oppositeNum(n/10, m);
cout << num << "\n";
m *= 10;
return num + x * (long int)m;
}
long int oppositeNum(int n){
if(n<0) return 0;
int m = 1;
return oppositeNum(n, m);
}
What did I change:
Removed the static modifier from m and instead passing it by reference. This allows to use the function more than one time during the program execution. (Also it would allow to use the function by multiple threads at once but I guess this is not a concern here.)
Removed the floating point function pow and instead just multiplying the variable m by ten each iteration.
Added a wrapper for the recursive function so it still can be called with just one argument. Additionally this allow to check for negative numbers only once.
The main source of problem was the function pow. Because it works on floating point numbers, it may not give exact results. It depends on the compiler and the processor architecture but generally you shouldn't expect it to give an exact result. Rounding it to integer additionally increases the difference.
return (num + float(x*pow(10,++m)));
just do this and it will work. the ans is wrong cos the pow func is giving out 4999 and 5999 that is why it changes the units place.
Try this:
return round(num+ (x*pow(10,++m)));
Sometimes the pow function will return the approximated result. e.g. pow(10, 5) could be 99999.9999999, if you round it, you'll get 100000 else it takes the floor value (I think).

C++ series summation code giving different answers on large input

I am adding numbers from 1 to n in C++. I have used both the iteration method and mathematical formula. The code works fine for up to 9 digits.
But when I give input a 10 digit number, the formula and iteration methods give separate answers.
I have tried to look it up on google but couldn't find any solution for this. My code:
#include <bits/stdc++.h>
using namespace std;
int main(){
unsigned long long i, n, sum = 0, out_put;
cout << "Sum of numbers from 1 to: ";
cin >> n;
/// using mathematical formula
out_put = n*(n+1);
out_put = out_put/2;
cout << " = " << out_put << endl;
/// using iteration
for (i=1; i<=n; i++){
sum = sum+i;
}
cout << " == " << sum << endl;
return 0;
}
How do know which one is the correct one? If I assume the formula can't be wrong then why is the iteration method giving incorrect answer? I have used unsigned long long to prevent overflow but still didn't work.
What you are seeing is overflow happening on your calculations at different points. 9,999,999,999 * 10,000,000,000 is ~9.9e19 while an unsigned long long holds ~1.8e19. So the result wraps around and you get one answer.
Your for loop is also going to overflow but it is going to do so at a different point meaning the answers will diverge from one another since the modulo arithmetic is happening with a smaller number.
Your problem is that n*(n+1) can be too large to store in an unsigned long long, even though the end result (half of that) which you calculate via iteration may still fit.
Assuming your unsigned long long has 64 bits, it can hold integers up to 18446744073709551615. Anything above that will restart from 0.
Edit: As Nathan points out, you can of course have both calculations overflow. The sum would still give the correct result modulo 2^64, but the direct calculation can be off because the division does not generally yield the same result modulo 2^64 after you have wrapped around.
#include <bits/stdc++.h>
using namespace std;
int main(){
unsigned long long i, n, sum = 0, out_put;
cout << "Sum of numbers from 1 to: ";
cin >> n;
/// using mathematical formula
out_put = n*(n+1);
out_put = out_put/2;
cout << " = " << out_put << endl;
/// using iteration
for (i=1; i<=n; i++){
sum = sum+i;
}
cout << " == " << sum << endl;
return 0;
}

Iterating primes using mpz_nextprime

In C++, I want to print the first n prime numbers (for this example let's assume n=1000).
In order to do this, I've found mpz_nextprime from the GMP library.
I'd assume you use it like this
int n = 2;
for(int i = 0; i < 1000; i++) {
n = mpz_nextprime(n);
cout << n << endl;
}
but this doesnt compile as mpz_nextprime takes two mpz_t arguments.
How can you use mpz_nextprime in this context?
The reason for mpz_nextprime using mpz_t instead of normal integer types like int or long is that after a certain point the prime numbers will be too large to be representable in a int or long.
Here's a snippet of code to print all up to the 1000th prime number:
#include <gmp.h>
int main() {
mpz_t n;
mpz_init(n);
mpz_set_ui(n, 2);
for (size_t i = 0; i < 1000; i++) { // first 1000 primes
mpz_nextprime(n, n);
cout << "The " << (i + 1) << "th " << " prime is " << mpz_get_ui(n) << endl;
}
}
Note that this code will only work up to a certain prime number because in order to print it, we convert it to an unsigned int using mpz_get_ui here.
If you want to print larger prime numbers, use mpz_get_str (but don't forget to free() the string if you use NULL as first parameter).

While loop logic clarification + harmonic series

This is my code for finding the sum of a harmonic series of 1/n. I want it to stop when the sum is greater than or equal to 15, but the code cannot run. Can anyone let me know what I'm doing wrong? It seems to follow the correct while loop structure. Thanks!
#include <iostream>
using namespace std;
int main ()
{
int divisor = 1;
int sum = 1;
while ((sum <= 15) && (divisor >=1))
{
sum = sum + (1/divisor);
divisor++;
}
cout << "You need " << divisor << " terms to get a sum <= 15" << endl;
return 0;
}
Your loop is actually running. However, your sum variable is of type int, and so is divisor.
1 (an int) / divisor (also an int) will return 1 or 0. This is because you are doing integer division. 1/1 == 1. However, 1/2 == 0, 1/3 == 0, etc... To solve this, cast divisor to double:
(1 / (double)divisor)
So that solves the issue of that segment returning only 1 or 0. However, you will still gain a sum of 1 as sum is of type int. Attempting to assign a double to an int variable will result in a truncation, or floor rounding. Sum will add the first 1, but it will remain 1 indefinitely after that. In order to solve this, change the type of sum to double.
Your assignment of sum = 1; is a logical error. Your result will be 1 higher than it should be. Your output statement is also mistaken... It should be...
cout << "You need " << divisor << " terms to get a sum > 15" << endl;
In addition, the condition of divisor >= 1 is needless... It is always greater than or equal to one because you assign it as 1 and are incrementing... If you do want a sum that is >= 15, change the while condition to...
while (sum < 15)
Your code should look like this...
#include <iostream>
using namespace std;
int main()
{
int divisor = 1;
double sum = 0; //Changed the type to double and assigned 0 rather than 1
while (sum <= 15) //While condition shortened...
{
sum = sum + (1 / (double)divisor); //Added type cast to divisor
divisor++;
}
//cout statement adjusted...
cout << "You need " << divisor << " terms to get a sum > 15" << endl;
return 0;
}