Arithmetic calculation anomaly - c++

I was trying to solve this exercise. Here is the solution:
#include <iostream>
using std::cout;
using std::cin;
int main()
{
int n, a;
cin >> n;
int* answers = new int[n]; // allocating memory
for (int i = 0; i < n; i++)
{
cin >> a;
answers[i] = (a - 32) * 5/9;
}
for (int i = 0; i < n; i++)
{
cout << answers[i] << ' ';
}
cout << '\n';
delete[]answers; //deallocating memory
system("pause");
return 0;
}
Now, notice when I change answers[i] = (a - 32) * 5/9; to answers[i] = (a - 32) * (5/9);.
Here, is the difference in the output respectively:
Without the brackets:
With the brackets:
What is this sorcery?
EDIT:
I understand why this can seem as a duplicate. My concern is not why 5/9 outputs 0. That is not my concern. My concern is what is the difference between the two following code:
answers[i] = (a - 32) * 5/9;
answers[i] = (a - 32) * (5/9);
When I do not use brackets, it works. But, when I use brackets it just outputs 0. So, the question is what is the bracket operator changing here? Please read the question carefully.

In (a - 32) * 5/9; the expression is done from left to right as ((a - 32) * 5)/9 because * and / have the same precedence with left-to-right associativity
If you do (a - 32) * (5/9) then it's exactly the same as (a - 32) * 0 because the expressions in () are done first, and 5/9 is an integer division that results in 0. To do a floating-point division then at least one side of the division must be a floating-point type. Try (a - 32) * (5.0/9) or (a - 32) * (5/9.0) and see

According to the C++ 5 / 9 is 0, because 5 and 9 are integers.
You should use double.
int main()
{
int n, a;
cin >> n;
int* answers = new int[n]; // allocating memory
for (int i = 0; i < n; i++)
{
cin >> a;
answers[i] = (a - 32) * 5/9.0; // 9.0 is double
}
for (int i = 0; i < n; i++)
{
cout << answers[i] << ' ';
}
cout << '\n';
delete[]answers; //deallocating memory
system("pause");
return 0;
}

With the brackets you are evaluated (int) 5 / 9 which is 0. Without the brackets, you are seeing the effect of * and / having the same operator precedence and they are evaluated left to right which means the expression would be evaluated as ((a - 32) * 5) / 9.
If you are doing fractional math, you usually assign the value to a floating point type (float, double etc). If you want indeed want the result as an int, you may still want to do the calculation as a floating point, and you usually do that implicitly by making one of the constants a floating point type like 5.0 / 9.

Related

Procedure that generate the polynomial coefficients and a function to calculate the value of it

So essentially, I'm trying to code a small block that should create or generate coefficients for polynomial n-degree that can be represented through vector which is a=[a0, a1..an] given the basic formula is
Well, the issue is when doing a function to get value of polynomial P from point "x" it returns value from entirely using Horner's Rule which it's not the same result as intended although not sure which one I should put on. The math basic explanation tells me at least something out of:
E.g: n=2; (A[i] stack terms by 4, 2, 1) and calculates P(value of x) = 4 * x ^ 0 – 2 * x ^ 1 + 1 * x ^ 2 = 4 – 2x + x2 = x2 – 2x + 4 = 4
With other words , can't find the culprit when for "x" value is meant to go through "i" variable numbered wrong by exponent and the result gets output for P(0)=7 while it shouldn't be and concrete as in P(0) = 0 ^ 2 – 2 * 0 + 4 = 4
Here's a little snippet went through so far, I would appreciate if someone could point me in the right direction.
double horner(const double&x, const int& n, const double& nn) {
if (n < 0)
return nn;
else {
double m; cin>>m;
return horner(x, n-1, nn*x+m);
}
}
int main() {
int n;double x;
cout << "n=";cin >> n;
cout << "x=";cin >> x;
cout << "P(0)=" << horner(x, n, 0);
return 0;
}
Edit: My brain farted for a moment somewhere while was coding and continuously revising the case, I forgot to mention what exactly are the parts of each variables for the program to avoid confusion yes, so:
n, polynomial grade;
p, polynomial coefficient;
x, the point in which evaluates;
And here given the grade equation to polynomial
which any negative and positive input terms adding by exponent to these coefficients are the steps that holds the result exception, hence the reason Horner's rule that it reduces the number of multiplication operations.
Edit: After few hours, managed to fix with polynomial evaluating issue, the only question remains how I'd suppose to generate coefficients using method std::vector ?
float honer(float p[], int n, float x)
{
int i;
float val;
val = p[n];
for (i = n - 1; i >= 0; i--)
val = val * x + p[i];
return val;
}
int main()
{
float p[20]; // Coefficient of the initial polynomial
int n; // Polynomial degree -n
float x; // Value that evaluates P -> X
cout << "(n) = ";
cin >> n;
for (int i = n; i >= 0; i--)
{
cout << "A[" << i << "]=";
cin >> p[i];
}
cout << "x:= ";
cin >> x;
cout << "P(" << x << ")=" << honer(p, n, x);
//Result (input):
//n: 2,
//P[i]: 4, -2, 1 -> x: 0, 1
// Result (output):
//P() = 4
}
Expect some certain output scenarios given below input if assigned:

C++ compound assignment and type conversion issue

I am calculating combination(15, 7) in C++.
I first used the following code and get the wrong answer due to a type promotion error.
#include <iostream>
int main()
{
int a = 15;
double ans = 1;
for(int i = 1; i <= 7; i++)
ans *= (a + 1 - i) / i;
std::cout << (int) ans;
return 0;
}
Output: 2520
So I changed ans *= (a + 1 - i) / i; to ans *= (double)(a + 1 - i) / i; and still get the wrong answer.
#include <iostream>
int main()
{
int a = 15;
double ans = 1;
for(int i = 1; i <= 7; i++)
ans *= (double) (a + 1 - i) / i;
std::cout << (int) ans;
return 0;
}
Output: 6434
Finally, I tried ans = ans * (a + 1 - i) / i, which gives the right answer.
#include <iostream>
int main()
{
int a = 15;
double ans = 1;
for(int i = 1; i <= 7; i++)
ans = ans * (a + 1 - i) / i;
std::cout << (int) ans;
return 0;
}
Output: 6435
Could someone tell me why the second one did not work?
If you print out ans without casting it to (int) you'll see the second result is 6434.9999999999990905052982270717620849609375. That's pretty darn close to the right answer of 6535, so it's clearly not a type promotion error any more.
No, this is classic floating point inaccuracy. When you write ans *= (double) (a + 1 - i) / i you are doing the equivalent of:
ans = ans * ((double) (a + 1 - i) / i);
Compare this to the third version:
ans = ans * (a + 1 - i) / i;
The former performs division first followed by multiplication. The latter operates left to right and so the multiplication precedes the division. This change in order of operations causes the results of the two to be slightly different. Floating point calculations are extremely sensitive to order of operations.
Quick fix: Don't truncate the result; round it.
Better fix: Don't use floating point for integral arithmetic. Save the divisions until after all the multiplications are done. Use long, long long, or even a big number library.
First one did not work because you have integer division there.
Difference btw second one and third one is this:
ans = ans * (double(a + 1 - i) / i); // second is equal to this
vs:
ans = (ans * (a + 1 - i)) / i; // third is equal to this
so difference is in order of multiplication and division. If you round double to integer instead of simply dropping fractional part you will get the same result.
std::cout << int( ans + 0.5 ) << std::endl;

Floating point error in C++ code

I am trying to solve a question in which i need to find out the number of possible ways to make a team of two members.(note: a team can have at most two person)
After making this code, It works properly but in some test cases it shows floating point error ad i can't find out what it is exactly.
Input: 1st line : Number of test cases
2nd line: number of total person
Thank you
#include<iostream>
using namespace std;
long C(long n, long r)
{
long f[n + 1];
f[0] = 1;
for (long i = 1; i <= n; i++)
{
f[i] = i * f[i - 1];
}
return f[n] / f[r] / f[n - r];
}
int main()
{
long n, r, m,t;
cin>>t;
while(t--)
{
cin>>n;
r=1;
cout<<C(n, min(r, n - r))+1<<endl;
}
return 0;
}
You aren't getting a floating point exception. You are getting a divide by zero exception. Because your code is attempting to divide by the number 0 (which can't be done on a computer).
When you invoke C(100, 1) the main loop that initializes the f array inside C increases exponentially. Eventually, two values are multiplied such that i * f[i-1] is zero due to overflow. That leads to all the subsequent f[i] values being initialized to zero. And then the division that follows the loop is a division by zero.
Although purists on these forums will say this is undefined, here's what's really happening on most 2's complement architectures. Or at least on my computer....
At i==21:
f[20] is already equal to 2432902008176640000
21 * 2432902008176640000 overflows for 64-bit signed, and will typically become -4249290049419214848 So at this point, your program is bugged and is now in undefined behavior.
At i==66
f[65] is equal to 0x8000000000000000. So 66 * f[65] gets calculated as zero for reasons that make sense to me, but should be understood as undefined behavior.
With f[66] assigned to 0, all subsequent assignments of f[i] become zero as well. After the main loop inside C is over, the f[n-r] is zero. Hence, divide by zero error.
Update
I went back and reverse engineered your problem. It seems like your C function is just trying to compute this expression:
N!
-------------
R! * (N-R)!
Which is the "number of unique sorted combinations"
In which case instead of computing the large factorial of N!, we can reduce that expression to this:
n
[ ∏ i ]
n-r
--------------------
R!
This won't eliminate overflow, but will allow your C function to be able to take on larger values of N and R to compute the number of combinations without error.
But we can also take advantage of simple reduction before trying to do a big long factorial expression
For example, let's say we were trying to compute C(15,5). Mathematically that is:
15!
--------
10! 5!
Or as we expressed above:
1*2*3*4*5*6*7*8*9*10*11*12*13*14*15
-----------------------------------
1*2*3*4*5*6*7*8*9*10 * 1*2*3*4*5
The first 10 factors of the numerator and denominator cancel each other out:
11*12*13*14*15
-----------------------------------
1*2*3*4*5
But intuitively, you can see that "12" in the numerator is already evenly divisible by denominators 2 and 3. And that 15 in the numerator is evenly divisible by 5 in the denominator. So simple reduction can be applied:
11*2*13*14*3
-----------------------------------
1 * 4
There's even more room for greatest common divisor reduction, but this is a great start.
Let's start with a helper function that computes the product of all the values in a list.
long long multiply_vector(std::vector<int>& values)
{
long long result = 1;
for (long i : values)
{
result = result * i;
if (result < 0)
{
std::cout << "ERROR - multiply_range hit overflow" << std::endl;
return 0;
}
}
return result;
}
Not let's implement C as using the above function after doing the reduction operation
long long C(int n, int r)
{
if ((r >= n) || (n < 0) || (r < 0))
{
std::cout << "invalid parameters passed to C" << std::endl;
return 0;
}
// compute
// n!
// -------------
// r! * (n-r)!
//
// assume (r < n)
// Which maps to
// n
// [∏ i]
// n - r
// --------------------
// R!
int end = n;
int start = n - r + 1;
std::vector<int> numerators;
std::vector<int> denominators;
long long numerator = 1;
long long denominator = 1;
for (int i = start; i <= end; i++)
{
numerators.push_back(i);
}
for (int i = 2; i <= r; i++)
{
denominators.push_back(i);
}
size_t n_length = numerators.size();
size_t d_length = denominators.size();
for (size_t n = 0; n < n_length; n++)
{
int nval = numerators[n];
for (size_t d = 0; d < d_length; d++)
{
int dval = denominators[d];
if ((nval % dval) == 0)
{
denominators[d] = 1;
numerators[n] = nval / dval;
}
}
}
numerator = multiply_vector(numerators);
denominator = multiply_vector(denominators);
if ((numerator == 0) || (denominator == 0))
{
std::cout << "Giving up. Can't resolve overflow" << std::endl;
return 0;
}
long long result = numerator / denominator;
return result;
}
You are not using floating-point. And you seem to be using variable sized arrays, which is a C feature and possibly a C++ extension but not standard.
Anyway, you will get overflow and therefore undefined behaviour even for rather small values of n.
In practice the overflow will lead to array elements becoming zero for not much larger values of n.
Your code will then divide by zero and crash.
They also might have a test case like (1000000000, 999999999) which is trivial to solve, but not for your code which I bet will crash.
You don't specify what you mean by "floating point error" - I reckon you are referring to the fact that you are doing an integer division rather than a floating point one so that you will always get integers rather than floats.
int a, b;
a = 7;
b = 2;
std::cout << a / b << std::endl;
this will result in 3, not 3.5! If you want floating point result you should use floats instead like this:
float a, b;
a = 7;
b = 2;
std::cout << a / b << std::end;
So the solution to your problem would simply be to use float instead of long long int.
Note also that you are using variable sized arrays which won't work in C++ - why not use std::vector instead??
Array syntax as:
type name[size]
Note: size must a constant not a variable
Example #1:
int name[10];
Example #2:
const int asize = 10;
int name[asize];

C++ Fibonacci Errors

I'm having some trouble with this non recursive Fibonacci function. I am using this array of numbers and passing it to FiboNR, however I am getting large negative values and Access Violation errors.
int n[15] = { 1,5,10,15,20,25,30,35,40,45,50,55,60,65,70 };
int FiboNR(int n) // array of size n
{
int const max = 100;
int F[max];
F[0] = 0; F[1] = 1;
for (int i = 2; i <= n; i++) {
F[n] = F[n - 1] + F[n - 2];
}
return (F[n]);
}
The function was one provided by the instructor and I assume its correct if he's giving it out but with these memory errors I don't fully understand what's going on. The only way I'm calling the in a loop to go through the array and outputting the answer like cout << FiboNR(n[i]);
First of all, your trouble is in loop. Replace:
F[n] = F[n - 1] + F[n - 2];
with:
F[i] = F[i - 1] + F[i - 2];
Because i is your iterator and n is only the limit.
Just FYI, the braces ( ) in return statement are not needed, you can ignore them.
I am using this array of numbers and passing it to FiboNR
You are not supposed to do that since FiboNR() excepts its argument to be an integer (one, not an array of integers). So you should pass only one number to your function, like: FiboNR(n[2]).
You get a negative numbers due to int overflow for int array (n > 46).
Change array type from int to long long.
Other solutions: change array type to float/double type with less precision of the results or use long arithmetic.
Type | Typical Bit Width | Typical Range
int | 4bytes| -2147483648 to 2147483647
Link: C++ Data Types
Example of code below.
#include <iostream>
long long FiboNR(int n);
long long FiboNR(int n) {
int const max = 100;
long long F[max];
if (n > max) {
n = max;
}
F[0] = 0;
F[1] = 1;
for (int i = 2; i <= n; i++){
F[i] = F[i - 1] + F[i - 2];
}
return (F[n]);
}
int main() {
for (int i=0; i < 100; i++) {
std::cout << "i = " << i << " : " << FiboNR(i) << std::endl;
}
return 0;
}

How to find maximum area among given triangles on C++

The input should be n - the number of triangles (1 <= n <= 20) and afterwards n rows of three doubles each (corresponding to each of the triangles' sides). The output should be the "n" which has the maximum triangle area.
#include <iostream>
#include <math.h>
using namespace std;
const int MAX_SIZE = 20;
int main()
{
int n, s, p;
double max = 0;
cin >> n;
int x[MAX_SIZE];
for (int i = 0; i < n; i++)
{
double y[2];
for (int j = 0; j < 3; j++)
cin >> y[j];
p = (y[0] + y[1] + y[2]) / 2;
s = sqrt(p * (p - y[0]) * (p - y[1]) * (p - y[3]));
if (s >= max) max = s;
}
cout << max;
return 0;
}
That's what I've done so far. "p" stands for semiparameter by the way.. - I'm using Heron's formula. I haven't even got it to "cout" the n in which the area is max but rather the maximum area itself, yet it doesn't work but gives me a massive error instead. Any ideas?
You've got a few problems:
You need to change s and p from ints to doubles (otherwise you'll get unwanted truncation of your results).
You need to change double y[2]; to double y[3]; (since you need three side lengths, not two).
Change s = sqrt(p * (p - y[0]) * (p - y[1]) * (p - y[3])); to s = sqrt(p * (p - y[0]) * (p - y[1]) * (p - y[2])); (since y[3] is out of bounds of your array).
Note also that you can get rid of your array x, since you don't seem to actually use it anywhere.
You are allocation only 2 doubles. You need 3, try double y[3].