Which way to overload the operator more efficiently and why? - c++

Which way more effective? Is there any difference this->X or just X? I think it 'void' version bcs compilator dont need to call contructor or smth, just add.
void operator+=(vect right)
{
this->x += right.x;
this->y += right.y;
}
void operator+=(vect right)
{
x += right.x;
y += right.y;
}
vect& operator+=(vect right)
{
x += right.x;
y += right.y;
return *this;
}

Start by not taking complex types as arguments by value if you care about efficiency.
vect& operator+=(vect const& right)
{
x += right.x;
y += right.y;
return *this;
}
this->x and just a plain x mean the same thing. They don't affect runtime at all. And finally, return vect& because it's idiomatic.

Version 1 and 2 do the exact same thing, no difference. Version 3 allows you to write
vecA += vecB += vecC += vecD;
There is no difference in terms of performance, the operator returns a reference to self, not a new object.

Related

Binary Division using Templated Big Integers

I am trying to implement a Division Binary Algorithm.
The code has some Logical Errors which I am still trying to figure out how to fix them.
myuint operator/(const myuint<T>& x)
{
myuint<T> temp;
myuint<T> result;
int count = 0;
for(int i = bits.size() - 1 ; i >= 0; --i)
{
temp.bits.push_back(bits[i]);
if(temp >= x)
{
count++;
*this = *this - x;
temp = 0;
}
}
result = count;
return result;
}
I am also overloading the >=, >, and == operators for the division.
The logical problem most probably is in the for loop . What should I do? Thanks
Full code can be accessible from here
== EDIT
What I am trying to achieve is this.
*this is 10100 (20 in decimal)
x is 100 (4 in decimal)
Get the first Bit (1).
Compare it to x
If the bit is greater than the value of x, count++, subtract x from *this. And then Start the loop again which a different *this size.
If the bit is small, then we move to the bit next to it so, now we have 2 bits (10) and we compare it to x.
Then I return the value of count which represents this number of divisions to reach 0.
Not a full answer, but here is the algorithm that you need to implement:
myuint div(const myuint& x, const myuint& y)
{
if (y == 0)
throw "division by zero";
myuint res = 0;
myuint one = 1;
unsigned int xLength = x.bitLength();
unsigned int yLength = y.bitLength();
while (xLength > yLength)
{
res += one << (xLength - yLength - 1);
x -= y << (xLength - yLength - 1);
xLength = x.bitLength();
}
if (x >= y)
return res+1;
return res;
}
So, I found a simple implementation of how to go around Binary Division.
The idea is that you subtract the LSH from the RHS until LHS is smaller RHS and keep a hold for the many times you subtracted RHS from LSH.
myuint operator/(const myuint<T>& x)
{
myuint<T> LHS = *this;
myuint<T> RHS = x;
myuint<T> result;
int count = 0;
bool flag = true;
if(LHS == RHS)
{
return 1;
}
else
{
do
{
if(LHS >= RHS)
{
LHS = LHS - RHS;
count++;
}
else if(LHS < RHS)
{
flag = false;
}
}while(flag);
}
result = count;
return result;
}
This may not be the most efficient way. But it gets the job done.

No operator = match these operands c++ even though said operator has been overloaded

I am trying to do a multiplication for my vector class and my matrix class.
Vector2f Matrix3x3::operator * (Vector2f & v) {
float vx = e11 * v.x + e21 * v.y + e31;
float vy = e12 * v.x + e22 * v.y + e32;
return Vector2f(vx, vy);
}
When a matrix multiplies with a vector it should return a vector. So I try to set the result to an already created vector object.
Vector2f d(12, 12);
Matrix3x3 m = translationMatrix(transX, transY);
d = m * d;
VS keeps underlining my "=" and says that no operators = match these operands, operands type are Vector2f and Vector2f. Even though I already overload assignment operator in Vector2f class
Vector2f & Vector2f::operator = (Vector2f & V) {
x = V.x;
y = V.y;
return *this;
}
I dont even know where I am wrong. Can someone explain it to me?
Matrix3x3::operator * returns by value, which means the object returned by m * d is a temporary, which can't be bound to lvalue-reference to non-const (i.e. Vector2f &); but it can be bound to lvalue-reference to const (i.e. const Vector2f &).
To solve the issue you chould change the parameter type of operator= to const Vector2f &, and you should do this also because the argument is supposed to be not modified inside operator=.
Vector2f & Vector2f::operator = (const Vector2f & V) {
x = V.x;
y = V.y;
return *this;
}

User defined calculation on structs/classes

I was once using Unity and they use a cool System to add and multiply vectors.
This is a short excerpt from the Reference (http://docs.unity3d.com/ScriptReference/Transform.html)
foreach (Transform child in transform) {
child.position += Vector3.up * 10.0F;
}
as you can see they can just add and multiply two Vectors (structs/classes) even though they could have different variables. Right now when I try to make such a calculation I have to add the x and y of a 2d float vector individually.
So how can i add structs like a
struct Vec2f{
float x;
float y;
};
together by writing
Vec2f c = a + b;
instead of
c.x = a.x + b.x;
c.y = a.y + b.y;
EDIT:
You need to overload operators like '+', '-' etc. in your struct. Example for addition:
struct Vec2f
{
float x;
float y;
Vec2f operator+(const Vec2f& other) const
{
Vec2f result;
result.x = x + other.x;
result.y = y + other.y;
return result;
}
};
EDIT 2:
RIJIK asks in comment:
Also i wonder if there are some tricks to make the functions not to be so repetetive. I mean if i now want to use an operator i have to make a function for each operator even if there is no big difference between the functions besides the operator which is used. How do you approach in implementing calculations or many operators?
So one thing you can do is use another operators in operator. Something like you can change subtraction to addition, by simply negate second number:
a - b becomes a + (-b)
Of course you need negation operator first in your struct to do that. Example code:
struct Vec2f
{
float x;
float y;
Vec2f operator+(const Vec2f& other) const
{
Vec2f result;
result.x = x + other.x;
result.y = y + other.y;
return result;
}
Vec2f operator-() const
{
Vec2f result;
result.x = -x;
result.y = -y;
return result;
}
// we use two operators from above to define this
Vec2f operator-(const Vec2f& other) const
{
return (*this + (-other));
}
};
One nice thing about this is that if you change addition for example than you don't need to change subtraction. It is changed automatically.
And as reply to this:
But i don't understand why i should make the functions constant.
Because then you can use this function with constant variables. For example:
const Vec2f screenSize = { 800.0f, 600.0f };
const Vec2f boxSize = { 100.0f, 200.0f };
const Vec2f sub = screenSize - boxSize;
I am using here also curly braces initialization, cause you don't define any constructor.

c++ overloading plus in an efficient way

I wrote a class like this:
class vector3D{
public:
double x,y,z;
}
and i overload + operator:
class vector3D{
public:
double x,y,z;
vector3D operator+(const vector3D &lhs)
{
vector3D temp(x+lhs.x,y+lhs.y,z+lhs.z);
return temp;
}
}
but using C=A+B is slower than
C.x = A.x + B.x;
C.y = A.y + B.y;
C.z = A.z + B.z;
i think it is because defining a vector3D instance in + overloading function. is there anyway to avoid this?
(FYI: i build with this flags: -Wall -Wextra -Wunreachable-code -m32 -DNDEBUG -O2 -D_LARGEFILE64_SOURCE -D_REETRANT -D_THREAD_SAFE)
EDIT:
this is how i test speed of two approach(in main() ):
//test bench
vector3D A(0.0,0.0,0.0), B(1e-9,1e-9,1e-9);
clock_t c = clock();
//case A
for(long int i=0;i<1000000000;i++)
{
A = A + B;
}
cout<<"case A took: "<<1.0*(clock()-c)/CLOCKS_PER_SEC<<A<<endl;
c = clock();
//case B
for(long int i=0;i<1000000000;i++)
{
A._x = A._x+B._x;
A._y = A._x+B._y;
A._z = A._x+B._z;
}
cout<<"case B took: "<<1.0*(clock()-c)/CLOCKS_PER_SEC<<A<<endl;
and the result is:
case A took: 5.539[1, 1, 1]
case B took: 1.531[2, 2, 2]
Since you're creating an additional object, it will carry some overhead. This is inherent.
However, looking at the "payload lines" you want, they are very similar to what you'd have in the body of operator+= adding some other:
vector3D &operator+=(const vector3D &other) // Note - no objects created.
{
x += other.x;
y += other.y;
z += other.z;
return *this; // Note - return by reference.
}
Of course, operator+= modifies its left operand (which is exactly why you have operator+ with its object-creation overhead).
In general, you should prefer operator+= for heavy objects where it is applicable (see also this question).
You may actually get a performance boost by collapsing this to one line and taking advantage of return value optimization:
vector3D operator+(const vector3D &lhs)
{
return vector3D(x+lhs.x,y+lhs.y,z+lhs.z);
}

returning a reference vs the type

I was looking over some code, in a textbook and they wrote:
Vector3 &operator =(const Vector3 &a) {
x = a.x; y = a.y; z = a.z;
return *this;
}
Does the following code produce the same, returning the type, not a reference to it(they both run):
Vector3 operator =(const Vector3 &a) {
x = a.x; y = a.y; z = a.z;
return *this;
}
my question: what is the difference between the two?
thanks
daniel
Vector3 a, b;
(a = b).x = 3;
In this code, a.x should end up with the value of 3. In the second example you give, that won't happen.
Vector3 b(1,2,3);
Vector3 a;
(a = b).x += 2.0;
Print(a.x);
If you use operator returning refernce, above code should print 3.0
In case of operator returning value it would print 1.0