C++ int float casting - c++

Why is m always = 0? The x and y members of someClass are integers.
float getSlope(someClass a, someClass b)
{
float m = (a.y - b.y) / (a.x - b.x);
cout << " m = " << m << "\n";
return m;
}

You need to use cast. I see the other answers, and they will really work, but as the tag is C++ I'd suggest you to use static_cast:
float m = static_cast&lt float &gt( a.y - b.y ) / static_cast&lt float &gt( a.x - b.x );

Integer division occurs, then the result, which is an integer, is assigned as a float. If the result is less than 1 then it ends up as 0.
You'll want to cast the expressions to floats first before dividing, e.g.
float m = static_cast<float>(a.y - b.y) / static_cast<float>(a.x - b.x);

You should be aware that in evaluating an expression containing integers, the temporary results from each stage of evaluation are also rounded to be integers. In your assignment to float m, the value is only converted to the real-number capable float type after the integer arithmetic. This means that, for example, 3 / 4 would already be a "0" value before becoming 0.0. You need to force the conversion to float to happen earlier. You can do this by using the syntax float(value) on any of a.y, b.y, a.x, b.x, a.y - b.y, or a.x - b.x: it doesn't matter when it's done as long as one of the terms is a float before the division happens, e.g.
float m = float(a.y - b.y) / (a.x - b.x);
float m = (float(a.y) - b.y) / (a.x - b.x);
...etc...

you can cast both numerator and denominator by multiplying with (1.0) .

Because (a.y - b.y) is probably less then (a.x - b.x) and in your code the casting is done after the divide operation so the result is an integer so 0.
You should cast to float before the / operation

You are performing calculations on integers and assigning its result to float. So compiler is implicitly converting your integer result into float

When doing integer division, the result will always be a integer unless one or more of the operands are a float. Just type cast one/both of the operands to a float and the compiler will do the conversion. Type casting is used when you want the arithmetic to perform as it should so the result will be the correct data type.
float m = static_cast<float>(a.y - b.y) / (a.x - b.x);

he does an integer divide, which means 3 / 4 = 0. cast one of the brackets to float
(float)(a.y - b.y) / (a.x - b.x);

You can use ios manipulators fixed(). It will allow you to print floating point values.

if (a.y - b.y) is less than (a.x - b.x), m is always zero.
so cast it like this.
float m = ((float)(a.y - b.y)) / ((float)(a.x - b.x));

Related

Optimizing Complex Mobius Transformations on a Fragment Shader

I'm developing my own graphics engine to render all sorts of fractals (like my video here for example), and I'm currently working on optimizing my code for Julia Set matings (see this question and my project for more details). In the fragment shader, I use this function:
vec3 JuliaMatingLoop(dvec2 z)
{
...
for (int k = some_n; k >= 0; --k)
{
// z = z^2
z = dcproj(c_2(z));
// Mobius Transformation: (ma[k] * z + mb[k]) / (mc[k] * z + md[k])
z = dcproj(dc_div(cd_mult(ma[k], z) + mb[k], dc_mult(mc[k], z) + md[k]));
}
...
}
And after reading this, I realized that I'm doing Mobius transformations in this code, and (mathematically speaking) I can use matrices to accomplish the same operation. However, the a, b, c, and d constants are all complex numbers (represented as ma[k], mb[k], mc[k], and md[k] in my code), whereas the elements in GLSL matrices contain only real numbers (rather than vec2). And so to my question: is there a way to optimize these Mobius transformations using matrices in GLSL? Or any other way of optimizing this part of my code?
Helper functions (I need to use doubles for this part, so I can't optimize by switching to using floats):
// Squaring
dvec2 c_2(dvec2 c)
{
return dvec2(c.x*c.x - c.y*c.y, 2*c.x*c.y);
}
// Multiplying
dvec2 dc_mult(dvec2 a, dvec2 b)
{
return dvec2(a.x*b.x - a.y*b.y, a.x*b.y + a.y*b.x);
}
// Dividing
dvec2 dc_div(dvec2 a, dvec2 b)
{
double x = b.x * b.x + b.y * b.y;
return vec2((a.x * b.x + a.y * b.y) / x, (b.x * a.y - a.x * b.y) / x);
}
// Riemann Projecting
dvec2 dcproj(dvec2 c)
{
if (!isinf(c.x) && !isinf(c.y) && !isnan(c.x) && !isnan(c.y))
return c;
return dvec2(infinity, 0);
}
I'm not sure if this will help, but yes you can do complex arithmetic by matrices.
If you regard a complex number z as a real two-vector with components Re(z), Im(z)
Then
A*z + B ~ (Re(A) -Im(A) ) * (Re(z)) + (Re(B))
(Im(A) Re(A) ) (Im(z)) (Im(B))
Of course you actually want
(A*z + B) / (C*z + D)
If you compute
A*z+b as (x)
(y)
C*z+d as (x')
(y')
Then the answer you seek is
inv( x' -y') * ( x)
( y' x' ) ( y)
i.e
(1/(x'*x'+y'*y')) * (x' y') * (x)
(-y' x') (y)
One thing to note, though, is that in these formulae, as in your code, division is not implemented as robustly as it could be. The trouble lies in evaluating b.x * b.x + b.y * b.y. This could overflow to infinity, or underflow to 0, even though the result of division could be quite reasonable. A commonly used way round this is Smith's method eg here and if you search for 'robust complex division' you'll find more recent work. Often this sort of thing matters little, but if you are iterating off to infinity it could make a difference.

Anyway to avoid floating point operation for Max Points on Line problem

I'm trying to solve "Max Points on Line" problem on Leet code. I inevitably need to do floating point operation to calculation Y-Intercept and slope of each line. Due to my past bad experience, I'm trying to avoid floating point operations as much as I can. Do you have any suggestion how I can do that here?
I am using LeetCode framework for development and pretty much just have access to standard C++ library.
Tried using double or long double but one of the test cases already pushes the numbers to the limits of the accuracy of these data types.
//P1[0] is X coordinate for point P1 and P1[1] is Y coordinate
long double slopeCalc( vector<int> &p1, vector<int> &p2 )
{
if( p1[0] == p2[0] && p1[1] == p2[1] )
{
return DBL_MIN;
}
if( p1[0] == p2[0] && p1[1] != p2[1] )
{
return DBL_MAX;
}
return ( (long double)p2[1] - (long double)p1[1] ) / ((long double)p2[0] - (long double)p1[0]);
}
long double yIntersectionCalc( vector<int> &p1, vector<int> &p2 )
{
if( p1[0] == p2[0] && p1[1] == p2[1] )
{
return DBL_MIN;
}
if( p1[0] == p2[0] && p1[1] != p2[1] )
{
return DBL_MAX;
}
return ((long double)p1[1]*(long double)p2[0] - (long double)p2[1]*(long double)p1[0]) / (long double)(p2[0] - p1[0]);
}
If the two points are (0, 0) and (94911150, 94911151) the slope is calculated as 1 which is inaccurate. I'm trying to avoid the floating point division if possible.
NOTE: Max Points on a Line problem is to be given points in 2D space (in this case integer coordinates) and find the maximum number of points that are on one line. E.g if the points are (0,0), (2,2), (4,3), (1,1) the answer is 3 which are points (0,0), (1,1), and (2,2)
In integer coordinates, the alignment test of three points can be written as the expression
(Xb - Xa) (Yc - Ya) - (Yb - Ya) (Xc - Xa) = 0
Assuming that the range of the coordinates requires N bits, the computation of the deltas takes N+1 bits, and exact evaluation of the expression takes 2N+2 bits at worse. There is little that you can do against that.
In your case, 64 bits integers should be enough.
A piece of advice: avoid working with the slope/intercept representation.
If you want to avoid using floating point, what you can do to determine if a point z is collinear with two other points x and y is to compute the determinant of the matrix
{{1,z1,z2},{1,x1,x2},{1,y1,y2}}
If the determinant is 0, then they are collinear. Since computing the determinant using the permutation definition involves only multiplication and addition/subtraction, all your computations will remain as integers. The reason it will be 0 is that the determinant is twice the area of the triangle with x,y,z as vertices,which is zero if and only if the triangle is degenerate.
Another approach would be to use Fraction objects, in particular the slope and the intercept of the lines defined by two integers are identified as Fractions ("rational numbers"), and a reduced fraction is identified by its numerator and denominator, so you can use the pair of fractions (slope,intercept) as identifiers and since you never use floating point arithmetic you won't need to deal with roundoff error. See https://martin-thoma.com/fractions-in-cpp/ for a sample implementation of Fractions, the important part is that you can use the arithmetic operators, and normalization.
EDIT: boost has a rational number library, if you want to use it https://www.boost.org/doc/libs/1_68_0/libs/rational/
Given points a,b,c, look at the slopes b,c make to a common point, a:
ba.x = b.x - a.x
ba.y = b.y - a.y
ba.s = ba.y / ba.x
ca.x = c.x - a.x
ca.y = c.y - a.y
ca.s = ca.y / ca.x
The points a,b,c are co-linear iff the lines AB and BC have a common slope, i.e.:
ba.s == ca.s
Substituting and rearranging to remove the divides:
ba.y / ba.x == ca.y / ca.x
ba.y * ca.x / ba.x == ca.y
ba.y * ca.x == ca.y * ba.x
Substitute in the original formulas for those, then a,b,c are co-linear iff:
(b.y - a.y) * (c.x - a.x) == (c.y - a.y) * (b.x - a.x)
Note that the determinant answer could also be rearranged into this form which proves this approach. But this form has just 2 multiplications rather than 12 for a naive determinant implementation.

Intersection of a line with a line segment in C++

The following is C++ code taken from CP3, which calculates the point of intersection between the line that passes through a and b, and the line segment defined by p and q, assuming the intersection exists. Can someone explain what it is doing and why it works (geometrically)?
// line segment p-q intersect with line A-B.
point lineIntersectSeg(point p, point q, point A, point B) {
double a = B.y - A.y;
double b = A.x - B.x;
double c = B.x * A.y - A.x * B.y;
double u = fabs(a * p.x + b * p.y + c);
double v = fabs(a * q.x + b * q.y + c);
return point((p.x * v + q.x * u) / (u+v), (p.y * v + q.y * u) / (u+v));
}
Note that this solution seems to be different to that explained here or in the Wikipedia page since this solution makes use of the absolute value function.
I've expanded the expressions that result for the point of intersection (x, y):
A good starting point would be to understand what to do to find line intersection yourself: https://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
Line Segment: y = ax + c
Line: y = bx + d
Intersection and
Now we'll just need to get a and c in terms of p and q and b and d in terms of A and B.
We know both of our slopes:
a = (p.y - q.y) / (p.x - q.x)
b = (A.y - B.y) / (A.x - B.x)
I tend to use the Point-Slope Form to find the y-intercept:
y -p.y= a(x -p.x) which will simplify to y = ax - (p.x * q.y - p.y * q.x) / (p.x - q.x)
y -A.y= a(x -B.x) which will simplify to y = ax - (A.x * B.y - A.y * B.x) / (A.x - B.x)
So if you'll permit me to mix our variables into math notation so simplification is simpler, our final equation for our intersection components is:
Once the fractions in the numerators and denominators have been combined into a single fraction, the denominator for both is seen to be (A.x - B.x)(p.x - q.x) So both denominators can be removed yielding:

What is the correct way to use C++ style casts to perform an expression at a desired precision?

Given the following:
int a = 10, b = 5, c = 3, d = 1;
int x = 3, y = 2, z = 2;
return (float) a/x + b/y + c/z + d;
This presumably casts our precision to float and then performs our sequence of divisions at floating point precision.
What is the correct way to update this using C++ style casts?
Should this really be rewritten as:
return static_cast<float>(a) / static_cast<float>(b) + ... ?
Start by correcting your code:
(float) a/x + b/y + c/z + d
produces 7.33333, while the correct result is 8.33333. Why? because b/y and c/z divisions are done in ints (demo).
The reason the result is incorrect is that division takes precedence over addition: your program needs to divide b by y and c by z before adding them to the result of division of a by x, which is float.
You need to cast one of the division operands to get this to work correctly. C cast works fine, but if you would rather use C++-style cast, here is how you can do it:
return static_cast<float>(a) / b + static_cast<float>(b) / y +
static_cast<float>(c) / z + d;
/ has higher precedence than +, so b/y will be performed in int, not in float.
The correct way to perform each division in float is to cast at least one operand to float:
static_cast<float>(a)/x + static_cast<float>(b)/y + static_cast<float>(c)/z + d
This is clearer than the equivalent C expression:
(float) a/x + (float) b/y + (float) c/z + d
Here one requires knowledge of precedence to realise that the cast to float binds tighter than the division.
return (float) a/x + b/y + c/z + d;
is not correct if you want to return the float value of sum of all divisions. In above expression only a/x is float division and rest of them are int division (because of heiger precedence of / operator than +) which will result in value truncation. Better to stick with
return (double)a/x + (double)b/y + (double)c/z + d;
int a = 10, b = 5, c = 3, d = 1;
int x = 3, y = 2, z = 2;
return (float) a/x + b/y + c/z + d;
This presumably casts our precision to float and then performs our sequence of divisions at floating point precision.
No, it casts a to float and so a/x is performed as a floating point divide, but b/y and c/z are integer divides. Afterwards, the sums are computed after converting the integer division results to float.
This is because casts are simply another operator, and they have higher precedence than + and /. Dividing float by an int or adding a float to an int causes the ints to be automatically converted to floats.
If you want floating point division then you need to insert casts so that they are applied prior to the divisions, and then the other values get automatically promoted.
return (float) a/x + (float) b/y + (float) c/z + d;
Casting using C++ syntax is exactly the same, except the syntax won't let you get confused about what's actually being cast:
return static_cast<float>(a)/x + static_cast<float>(b)/y + static_cast<float>(c)/z + d;
You can also use constructor syntax, which also has the benefit of clearly showing what's cast:
return float(a)/x + float(b)/y + float(c)/z + d;
Or you can simply use temporary variables:
float af = a, bf = b, cf = c;
return af/x + bf/y + cf/z + d;
The cast is only necessary with division operation. And you can lighten syntax this way:
return 1.0*a/x + 1.0*b/y + 1.0*c/z + d;
This will compute the result as double type, that gets automatically casted to float if the function returns this type.

Why am I getting zero for all values in this expression?

Following is a fragment of a program for deducing whether or out 2 lines intersect.
P and P2 are CPoint objects marking the start and end point of one of the 2 lines.
double m1,m2; //slopes
double b1,b2; //y-intercepts
double y,x; //intersection point
m1=(max(P.y,P2.y) - min(P.y,P2.y)) /( max(P.x,P2.x) - min(P.x,P2.x) );
For some reason I'm always getting m1 to be 0. Why's that?
If your CPoint class is a point with integer coordinates, you have to do some conversion here to get the result you want. See the following demonstration of the problem. Consider two points P = (1, 4) and P2 = (5, 3):
m1=( max(P.y,P2.y) - min(P.y,P2.y) ) / ( max(P.x,P2.x) - min(P.x,P2.x) );
^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^ ^^^^^^^^^^^^^
4 3 5 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1 4
However, in integer division, 1 / 4 is 0, but you want the result to be 0.25. The fact that the result variable has a type of double doesn't change the value (and type) of the expression.
To solve this problem, you have to cast the parts of your expression just before it becomes relevant that they are to be considered as non-integral numbers. In your case this are the operands of the division, so that it will be a floating point division. (Casting the result of the division will also not help.)
m1 = static_cast<double>( max(P.y,P2.y) - min(P.y,P2.y) )
/ static_cast<double>( max(P.x,P2.x) - min(P.x,P2.x) );
Note that casting the second operand is optional, as double / int always uses floating point division.
Also note that your expression calculates the absolute value of the slope. You might want to calculate the signed slope.
Something you can improve in your code (this won't solve the problem above): Instead of subtracting the min of the max of the difference, just take the absolute value of the difference:
m1 = static_cast<double>( abs(P.y - P2.y) )
/ static_cast<double>( abs(P.x - P2.x) );
Since in C++, abs is a template function (in C it's a macro, urgh...), you can also force a result type using explicit template types:
m1 = abs<double>(P.y - P2.y)
/ abs<double>(P.x - P2.x);
Also, as the calculation of a slope between two given points seems to be a commonly used function, you can implement this as a free-standing function on two CPoints:
double absoluteSlope(const CPoint & p, const CPoint & q) {
return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}
Even better, to make use of C++ templates, implement it on a generic class which has the members x and y:
template<class T>
double absoluteSlope(const T & p, const T & q) {
return abs<double>(p.y - q.y) / abs<double>(p.x - q.x);
}
This solution now works for your CPoint instance with integer coordinates as well as a (maybe upcoming) CPointF class with float / double coordinates.
As already warned above, this calculates the absolute slope. To change this to a mathematically correct (signed) slope, just replace abs with static_cast:
template<class T>
double slope(const T & p, const T & q) {
return static_cast<double>(p.y - q.y) / static_cast<double>(p.x - q.x);
}
The division A/B should A/(double)B. Use this in your code.
Fabs instead of abs too.