c++ getting a negative value when adding two absolute (positive) values [duplicate] - c++

This question already has answers here:
Adding two positive integers gives negative answer.Why?
(4 answers)
Closed 5 years ago.
I am getting a strange problem. I am getting a negative value when adding two absolute (positive) values. I am trying to solve this exercise from codingame (link: https://www.codingame.com/ide/puzzle/network-cabling).
I tried debugging and I got this:
X[i]: 19715507 X[j]: 938059973 // This one is good
temp: 918344466
Y[i]: 470868309 Y[j]: -816049599 //Something is wrong here
temp: -2089704922
This code is probably not a good solution to the exercise and I will need to improve it, but I still can't figure it out why the value is negative.
Please help.
Thank you.
Code:
int main()
{
int N;
int X[100000];
int Y[100000];
cin >> N; cin.ignore();
for (int i = 0; i < N; i++) { //reading all input
cin >> X[i] >> Y[i]; cin.ignore();
}
int ilgis=0; //ilgis means length
for(int i=0; i<N-1; i++){ //"min" is set to a very high value
//so it could find a lower value later
// "not the best solution"
int min=99999999999999999999; //shortest distance between houses
for(int j=0; j<N; j++){ // here I am trying to find the shortest
// distance from one house to another
if(j!=i){ //I can't count distance from the same house because
// it would be 0
int temp=0;
//counting the distance differently if the
//value is negative or positive
if(X[i]<=0&&X[j]<=0) temp+=abs(abs(X[i])-abs(X[j]));
else if(X[i]<=0&&X[j]>=0) temp+=abs(X[i])+abs(X[j]);
else if(X[i]>=0&&X[j]>=0) temp+=abs(X[i]-X[j]);
else if(X[i]>=0&&X[j]<=0) temp+=(X[i])+abs(X[j]);
//same with y axis
if(Y[i]<=0&&Y[j]<=0) temp+=abs(abs(Y[i])-abs(Y[j]));
else if(Y[i]<=0&&Y[j]>=0) temp+=abs(Y[i])+abs(Y[j]);
else if(Y[i]>=0&&Y[j]>=0) temp+=abs(Y[i]-Y[j]);
else if(Y[i]>=0&&Y[j]<=0) temp+=(Y[i])+abs(Y[j]);
if(min>temp) min=temp;
}
} //if i found the shortesst distance between
//houses I add that value to overall distance
// and continue until all houses are checked
ilgis+=min;
}
cout<<ilgis<<endl;
}
Input of the exercise:
8
-28189131 593661218
102460950 1038903636
938059973 -816049599
-334087877 -290840615
842560881 -116496866
-416604701 690825290
19715507 470868309
846505116 -694479954

The maximum value for int is 2147483647 (which is 2^31-1, assuming int has 32 bits width). You can check it with
std::numeric_limits<int>::max();
You might want to min with this value here. And also use long long as your type for calculations here.

Related

Simple calculator C++ loop [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 months ago.
The community reviewed whether to reopen this question 4 months ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I am a student in my first year.
Could someone help me with an assignment?
Simple calc C++
In the first line the number of tests n. In the next n lines operations Each operation contains the operation type (+ *) the number of k numbers to be processed, and k numbers
Output
Result
Example
Input
3
+ 3 3.1 5.2 -8.3
* 2 1 3.3
+ 1 3
Output
0
3.3
3
My code
int n, k;
char x;
cin >> n;
int tab[100];
for (int i = 0; i < n; i++)
{
cin >> x >> k;
for (int j = 0; j < k; j++)
{
cin >> tab[j];
if (x == '+')
{
tab[j] += tab[j + 1];
}
if (x == '*')
{
tab[j] *= tab[j + 1];
}
cout << tab[j];
}
}
return 0;
}
There are a few problems.
your tab is of type int so it can only store integers e.g.: 1,2,3,4,5 not floating point numbers like 1.3 2.5 3.3, you should consider changing tab to be of type float.
your loop logic and indexing is totally wrong, and you are accessing the wrong elements, you should have some sort of accumulator variable that will accumulate the results instead of storing them in an array. e.g.:
float accumulator = 0;
cin >> input_number;
accumulator += input_number;`
the best advice i can give you is to learn to use the debugger, the debugger is your friend, you should use it to walk through your code, line by line and understand what each lines does to each variable, and read the contents of each variable, i cannot recommend a certain source for learning to use a debugger as it depends on your IDE, but you should maybe check a video on using debugger with IDE X, it can be a good start for learning to use an IDE GUI.
The issues are many. Just some:
The purpose of tab is unclear. You do not need to store the operands, you can accumulate a result in a single value.
In any event tab[j + 1]; is not initialised at point of use.
If you want to output the results after all the input as indicated in the question then you do need somewhere to store the results for later output.
You do need to output the results.
The input and output types do need to be a floating-point type.
Greater clarity of thought might arise if you were to use clear variable names that reflected their purpose and perhaps some comments. If you have to explain what the code does (even to yourself) often you spot the errors. A good technique is to write the comments first, to explain what you need to code rather than explaining the code you have written and assume erroneously to be correct. Also you need to get out of that "all variables at the top" habit.
Example:
#include <iostream>
int main()
{
// Get number of calculations
int ncalc = 0 ;
std::cin >> ncalc ;
// Create array for results
double* result = new double[ncalc] ;
// For each calculation
for( int calc = 0; calc < ncalc; calc++ )
{
// Get the operator
char op = 0 ;
std::cin >> op ;
// Get the number of operands
int noperands = 0 ;
std::cin >> noperands ;
// Get initial operand in accumulator
double accumulator = 0 ;
std::cin >> accumulator ;
// For each remaining operand...
for( int i = 1; i < noperands; i++)
{
// Get the operand
double operand = 0 ;
std::cin >> operand ;
// Perform the operation
switch( op )
{
// For +, accumulate sum
case '+' : accumulator += operand ; break ;
// For * accumulate product
case '*' : accumulator *= operand ; break ;
}
}
// Store accumulated result
result[calc] = accumulator ;
}
// Output results
for( int calc = 0; calc < ncalc; calc++ )
{
std::cout << result[calc] << '\n' ;
}
delete[] result ;
return 0;
}

double or float type data rounds off automatically [duplicate]

This question already has answers here:
How do I print a double value with full precision using cout?
(17 answers)
std::cout with floating number
(3 answers)
Closed 2 years ago.
I was trying to find maximum and minimum of given numbers with this code
double a[50], max, min; long int k,i,j,n;
cout<<"How many numbers you want to examine with";
cin>>n;
cout<<"type the numbers you want to know maximum and minimum of";
i = 0;
while (i<n)
{
cin>>a[i];
i++;
}
max = a[0];
for (j=0; j<n; j++){
if (a[j] >= max) {
max = a[j];
}
}
cout<<"Maximum of given numbers is "<<max <<"\n";
min = a[0];
for (k=0; k<n; k++){
if (a[k]<=min){
min = a[k];
}
}
cout<<"Minimum of given numbers is "<< min;
Then I gave input values as n = 3 & three values to be 34543.54, -6.543467, 0.
But I got answers which are rounded off like this
Maximum of given numbers is 34543.5
Minimum of given numbers is -6.54347
I didn't use and round off functions, also I'm using double for array, max and min then why am I getting rounding off values. Is there any way to avoid it?

What does the dot mean in the printf function

I'm solving this problem:
Vanya walks late t night along a straight street of length l, lit by n lanterns. Consider the coordinate system with the beginning of the street corresponding to the point 0, and its end corresponding to the point l. Then the i-th lantern is at the point ai. The lantern lights all points of the street that are at the distance of at most d from it, where d is some positive number, common for all lanterns.
Vanya wonders: what is the minimum light radius d should the lanterns have to light the whole street?
In some test it gives WA expected: ** *'22258199.50000*00', found: '22258200.0000000'
but in some tests where answer is not integer, my code output correct answer. (i.e. it can output double)
when I saw the solution there was "printf("%.10f", maxdist/2.)" instead "cout << (double)maxdist/2"
questions:
why doesn't my code work?
What means the dot at the end of "maxdist/2."?
Why there is no "&" before variable maxdist?
#include <bits/stdc++.h>
using namespace std;
#define all(x) (x).begin(), (x).end()
int main(){
int n, l;
cin >> n >> l;
vector<int> v;
for(int i = 0; i < n; i++){
int x;
cin >> x;
v.pb(x);
}
sort(all(v));
int maxdist = 2*max(v[0], l-v[n-1]);
for(int i = 0; i < n-1; i++){
maxdist = max(maxdist, v[i+1] - v[i]);
}
cout << (double)maxdist/2;
}
"%.10f" - means floating value of the variable upto 10 decimal places and "." means the decimal point after which any number followed by f will decide how many decimal places the answer would go.

C++ program doesn't fully execute iteration [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
The program I've written is supposed to take in two user inputs (one being the number we're meant to check whether it's k-hyperperfect or not, the other being a maximum k-value.) if the input integer is k-hyperperfect in the range of 1 to the inputted maximum k-value, then the output should be that k-value. For example, if the input integer is 21 and the maximum k-value is 100 then the output should be 2.
My program gives the correct output for (the first number is the input integer, the second number is the k-max value, the third number is output value) ...
21 (input integer) 100 (k-max) --> 180
301 100 --> 6
12211188308281 100 --> 0
-301 100 --> 0
21 -5 --> 0
However, it doesn't correctly execute for 12211188308281 and 200 (it gives me 0 when it should give me 180). I've run my code through a step by step visualizer and it seems to just abruptly stop execution when i = 496 in the for loop within the else statement. But I don't understand why since it executes correctly for 5 other test runs.
#include <iostream>
using std::cout; using std::cin; using std::endl; using std::fixed;
int main () {
int number;
int kmax;
int sum = 0 ;
int hyper = 0;
std::cin >> number;
std::cin >> kmax;
if (number <= 6 or kmax < 1) {
std::cout << "0" << "\n";
}
else {
for (int i=1;i<=number;i++) {
if (number%i==0 and i != 1 and i != number){
sum+= i;
}
}
}
for (int k=1; k <= kmax; k++) {
hyper = ((sum)*k) + 1;
if (hyper == number) {
std::cout << k << endl;
break;
}
}
}
You need to check that numbers read through std::istreams (like std::cin) are read successfully. As the value that you enter for number is too large to store in an integer your read will fail. For example you could change your code to:
int main()
{
int number;
std::cin >> number;
if ( !std::cin )
{
std::cout << "invalid value: " << number << "\n";
return 1;
}
else
{
std::cout << "valid value: " << number << "\n";
}
// calculate answer
return 0;
}
You would then see your program printing "invalid value: 2147483647" if you have a c++11 compliant compiler or an undefined number if you have an older compiler.
Now that you have implemented reading values correctly the fix to your issue is to use a larger integer type like int64_t which is able to hold your number.
As already noted, the int type in your machine isn't big enough to store the value 12,211,188,308,281.
The C++ standard only mandates it to be capable of storing a value up to 32,767 and even in the (now common) case of a 32-bit int or long int), the limit would be 2,147,483,647. So you need a long long int or an int64_t (if it's present in your implementation).
A simple check like
if (std::cin >> number >> kmax ) { // perform calculations...
Would have shown the error sooner.
That beeing said, there are also some simple changes that could be done to the posted code in order to make it more efficient. The first loop can be optimized considering the "symmetry" of the divisors of a given number: meaning, if n is divisible by a, so that b = n/a is a whole number, b too is a divisor of n. This will limit the number of iterations to the square root of n, instead of n.
long long int number,
kmax,
sum = 0;
// ...
long long int temp = number,
i = 2;
for (; i * i < number; i++) {
if (number % i == 0) {
temp = number / i;
sum += i + temp;
}
}
if (i * i == number) {
sum += i;
}
There probably are better algorithms, but I'm unfamiliar with those.
The second loop, in my opinion, is unnecessary. The value k can be calculated directly:
if ( (number - 1) % sum == 0) {
std::cout << (number - 1) / sum << '\n';
}
You are assigning a too long value 12211188308281 to integer "number", which can't contain it fully and it is getting truncated to 596285753. You can add a print statement to print it.
std::cout<<number;
which will print 596285753.
As suggested you should use long long int. Again its dependent on the software platform running on your system.

Find closest number C++ using arrays, floats

I need to find the closest (and minor) number to the average in the given numbers. For example:
If the given numbers are 1,2,3,4,5 the average will be 3, and the closest numbers are 2 and 4 but the minor is 2 so the result should be 2.
Or, if the given numbers are 1, 325, 350, 299 the average will be 243.75 so the closest number is 299.
int best = a[0];
for (i = 1; i < count; ++i)
best = abs(a[i] - x) < abs(best - x) ? a[i] : best;
Your code's almost right... you just need to also check if the distance from the average x is the same as best's distance, but on the minor side while best isn't....
double i_delta = abs(a[i] - x);
double x_delta = abs(best - x);
if (i_delta < x_delta)
best = a[i];
else if (i_delta == x_delta && a[i] < best)
best = a[i];
(You have to do one pass through the values to calculate the average, so your overall algo's going to be O(n). So an extra iteration like you're using isn't reducing the overall big-O efficiency... all good.)
This isn't tough and you should be able to do that. I'm assuming this is question from your school homework and you are not in mood
int closest(int* array, int size){
//Calculating sum for finding average first
double sum = 0.0;
for (int i=0; i< size; i++){
sum+= array[i]*1.0;
}
//Here is our average
double average = sum/size;
//Assuming initial answer is very huge so that every other comparison is less than this
int answer = 100000000;
for (int i=0; i< size; i++){
//Finiding the difference for current element
double temp = abs(array[i]-average);
double temp1 = abs(answer - average);
//If current difference is less than previous one that replace the previous answer
if (temp < temp1) answer = array[i];
//If they are equal then accept the minor one
else if (temp == temp1){
if (array[i]< answer) answer = array[i];
}
}
return answer;
}
P.S. This isn't good practice to ask such question to ask here. You should have attempted it first and then posted your question with your attempt.