I have a class , vector which inherited from a "raw vector"
struct vector2raw {
real_t x, y;
};
struct vector2 : public vector2raw {
vector2() { null(); }
vector2(real_t x, real_t y) { this->x = x; this->y = y; }
vector2(const vector2 &v) { x = v.x; y = v.y; }
and so on
Now I want to compare two numbers, one v.y=4 from v = (5.41, 4), another min.y = 4 from min=(4,4).This is only the strange case when I compare two equal numbers, other cases are executed correctly. I get always false on (4>=4) ( v.y>=min.y) . What can be the problem?
real_t is defined to double
UPD: this is written in C++
Apparently (you're not giving a reproducible example) you're comparing floating point numbers with ==.
That's an ungood idea unless those numbers happen to be integral values, and for beginners it's an ungood idea in general.
Two floating point values can appear to be equal, e.g. they give the same presentation when you don't request presentation of additional decimals, while in reality they differ in some otherwise very insignificant digit.
In the old days beginners who encountered this problem used to be referred to “What every scientist should know about floating point numbers” (or thereabouts, title from fallible memory).
In the last few years I have been criticized for giving that reference, because real technical stuff and so on is, allegedly, too hard for today's students. And people have suggested more easy to digest alternatives, sort of like Wikipedia's simple edition. However, I can't remember any of them.
Related
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
We had some weird misbehavior in our vector class. It taught us a valuable lesson.
class Vector3D
{
float x, y, z, w;
public:
Vector3D( float ax, float ay, float az, float aw )
: x(ax), y(ay), z(az), w(aw)
{}
Vector3D( float ax, float ay, float az ) // for when you don't care about w
: x(ax), y(ay), z(az)
{}
void Assign( const Vector3D& rhs )
{
x = rhs.x;
y = rhs.y;
z = rhs.z;
w = rhs.w;
}
bool operator==( const Vector3D& o )
{
return (x==o.x && y==o.y && z==o.z && w==o.w);
}
// lots more stuff
}
int main()
{
Vector3D a(1.0f,2.0f,3.0f);
Vector3D b(4.0f,5.0f,6.0f);
a.Assign(b);
bool result=(a==b); // Expected: true. Actual: false, sometimes
}
For a while it looked like there was a bug in the Assign function. We would use it to copy the value of one vector to another, but later on the code would fail to match points that we knew should be identical. Data breakpoints were set, and failed to be hit. Heads were scratched. Eventually we added code to the end of Assign that immediately called operator== to check that the two vectors were the same... and they weren't.
What went wrong?
The problem was that the second constructor, the one taking just 3 parameters, wasn't initializing w. We were very concerned about the performance of our code, and in cases where we knew we would only use x.y,and z we didn't want to use any CPU power on the fourth member variable.
Eventually, we ended up seeing an object whose w happened to contain a pattern of bits corresponding to IEEE NaN. One of the interesting things about those is that when you compare NaN to NaN, the comparison always fails, even if the bit patterns are the same. So our operator== method, comparing uninitialized w values, decided that the two were not the same.
Lesson learned: never use uninitialized data.
With this question as base, it is well known that we should not apply equals comparison operation to decimal variables, due numeric erros (it is not bound to programming language):
bool CompareDoubles1 (double A, double B)
{
return A == B;
}
The abouve code it is not right.
My questions are:
It is right to round to both numbers and then compare?
It is more efficient?
For instance:
bool CompareDoubles1 (double A, double B)
{
double a = round(A,4);
double b = round(B,4)
return a == b;
}
It is correct?
EDIT
I'm considering round is a method that take a double (number) and int (precition):
bool round (float number, int precision);
EDIT
I consider that a better idea of what I mean with this question will be expressed with this compare method:
bool CompareDoubles1 (double A, double B, int precision)
{
//precition could be the error expected when rounding
double a = round(A,precision);
double b = round(B,precision)
return a == b;
}
Usually, if you really have to compare floating values, you'd specify a tolerance:
bool CompareDoubles1 (double A, double B, double tolerance)
{
return std::abs(A - B) < tolerance;
}
Choosing an appropriate tolerance will depend on the nature of the values and the calculations that produce them.
Rounding is not appropriate: two very close values, which you'd want to compare equal, might round in different directions and appear unequal. For example, when rounding to the nearest integer, 0.3 and 0.4 would compare equal, but 0.499999 and 0.500001 wouldn't.
A common comparison for doubles is implemented as
bool CompareDoubles2 (double A, double B)
{
return std::abs(A - B) < 1e-6; // small magic constant here
}
It is clearly not as efficient as the check A == B, because it involves more steps, namely subtraction, calling std::abs and finally comparison with a constant.
The same argument about efficiency holds for you proposed solution:
bool CompareDoubles1 (double A, double B)
{
double a = round(A,4); // the magic constant hides in the 4
double b = round(B,4); // and here again
return a == b;
}
Again, this won't be as efficient as direct comparison, but -- again -- it doesn't even try to do the same.
Whether CompareDoubles2 or CompareDoubles1 is faster depends on your machine and the choice of magic constants. Just measure it. You need to make sure to supply matching magic constants, otherwise you are checking for equality with a different trust region which yields different results.
I think comparing the difference with a fixed tolerance is a bad idea.
Say what happens if you set the tolerance to 1e-6, but the two numbers you compare are
1.11e-9 and 1.19e-9?
These would be considered equal, even if they differ after the second significant digit. This may not what you want.
I think a better way to do the comparison is
equal = ( fabs(A - B) <= tol*max(fabs(A), fabs(B)) )
Note, the <= (and not <), because the above must also work for 0==0. If you set tol=1e-14, two numbers will be considered equal when they are equal up to 14 significant digits.
Sidenote: When you want to test if a number is zero, then the above test might not be ideal and then one indeed should use an absolute threshold.
If the round function used in your example means to round to 4th decimal digit, this is not correct at all. For example, if A and B are 0.000003 and 0.000004 they would be rounded to 0.0 and would therefore be compared to be equal.
A general purpose compairison function must not work with a constant tolarance but with a relative one. But it is all explained in the post you cite in your question.
There is no 'correct' way to compare floating point values (Even a f == 0.0 might be correct). Different comparison may be suitable. Have a look at http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
Similar to other posts, but introducing scale-invariance: If you are doing something like adding two sets of numbers together and then you want to know if the two set sums are equal, you can take the absolute value of the log-ratio (difference of logarithms) and test to see if this is less than your prescribed tolerance. That way, e.g. if you multiply all your numbers by 10 or 100 in summation calculations, it won't affect the result about whether the answers are equal or not. You should have a separate test to determine if two numbers are equal because they are close enough to 0.
I would like to know how would one represent infinity if there is no built-in function for you to do so.
I know that if we are using float or double, we will be able to use infinity() with #include <limits>. But if I need to use int or in the case of NTL, ZZ, how should I represent infinity? Should I write something new? How is it represented in C++?
Edit: I'm posing this question because I would like to implement an addition algorithm for point on an elliptic curve. So, I'll need infinity to represent the point of infinity. I was wondering if I'll be better off using projective coordinates and have [0:1:0] to represent the point at infinity, but wanted to explore the infinity in int or ZZ option first.
In general, if you are running into infinity on a finite precision machine then you are not addressing the problem at hand correctly with your computational approach. You should either analytically deal with the infinity before hand or find a means to appropriately avoid it in finite precision. For instance, if you had to deal with f(x)=sin(x)/x you probably wouldn't want to let your code evaluate this in finite precision at x = 0. Instead you would want to check if x is 0 and then return f(0) = 1.0.
What about just a symbolic representation such that it "acts", in a general sense, as infinity would?
You can certainly do something like that. For most computational problems that wont get you anywhere useful. A simple way to approach that would be to create your own data types and override all of the operators to handle infinity appropriately. Not all infinities are the same though so you would need to deal with that issue. For example, you might define a customized float to be something like
class MyFloat
{
public:
MyFloat(float a):
m_val(a),
m_isInf(false),
m_orderInf(0)
{}
bool isInf(){return m_isInf;}
int orderInf(){return m_orderInf;}
float value(){return m_val;}
// define custom operators
MyFloat & operator+= (MyFloat const & rhs)
{
if(rhs.isInf() || m_isInf)
{
m_orderInf = m_orderInf > rhs.orderInf() ? m_orderInf : rhs.orderInf();
m_isInf = true;
}
else
{
m_val += rhs.value();
}
return *this;
}
// other operators you would need to define
MyFloat & operator/= (MyFloat const & rhs);
MyFloat & operator*= (MyFloat const & rhs);
private:
float m_val;
bool m_isInf;
int m_orderInf;
};
NOTE: You will need to give a lot of thought as to how to treat both zeros and infinities. The above code is not well thought out, but I hope it gives you something to think about.
In C++, let's say I have a number x of type T which can be an integer or floating point type. I want to find the largest number y of type T for which y < x holds. The solution needs to be templated to work transparently with both integers and floating point numbers. You may ignore the edge case where x is already the smallest number that can be represented in a T.
POSSIBLE USE CASE: This question was marked as too localized, hence I would like to provide a use case which I think is more general. Note that I'm not the original author of the OP.
Consider this structure:
struct lower_bound {
lower_bound(double value, bool open) : value(open? value+0.1 : value) {}
double value;
bool operator()(double x) { return x >= value; }
};
This class simulates an lower bound which can either be open or closed. Of course, in real (pun intended) life we can not do this. The flowing is impossible (or at least quite tricky) to calculate for S being all real numbers.
However, when S is the set of floating point numbers, this is a very valid principle, since we are dealing with essentially a countable set; and then there is no such thing as an open or closed bound. That is, >= can be defined in terms of > like done in the lower_bound class.
For code simplicity I used +0.1 to simulate an open lower bound. Of course, 0.1 is a crude value as there may be values z such that value < z <= value+0.1 or value+0.1 == value in a floating point representation. Hence #brett-hale answer is very useful :)
You may think about another simpler solution:
struct lower_bound {
lower_bound(double value, bool open) : open(open), value(value) {}
bool open;
double value;
bool operator()(double x) { return (open ? x > value : x>=value); }
};
However, this is less efficient as the sizeof(Lower_bound) is larger, and operator() needs to execute a more complicated statement. The first implementation is really efficient, and can also be implemented simply as a double, instead of a structure. Technically, the only reason to use the second implementation is because you assume a double is continuous, whereas it is not and I guess it will not be anywhere in the foreseeable future.
I hope I have created and explained a valid use case, and that I have not offended the original author.
If you have C++11, you could use std::nextafter in <cmath> :
if (std::is_integral<T>::value)
return (x - 1);
else
return std::nextafter(x, - std::numeric_limits<T>::infinity());
I am doing some C++ computational mechanics (don't worry, no physics knowledge required here) and there is something that really bothers me.
Suppose I want to represent a 3D math Vector (nothing to do with std::vector):
class Vector {
public:
Vector(double x=0., double y=0., double z=0.) {
coordinates[0] = x;
coordinates[1] = y;
coordinates[2] = z;
}
private:
double coordinates[3];
};
So far so good. Now I can overload operator[] to extract coordinates:
double& Vector::operator[](int i) {
return coordinates[i] ;
}
So I can type:
Vector V;
… //complex computation with V
double x1 = V[0];
V[1] = coord2;
The problem is, indexing from 0 is NOT natural here. I mean, when sorting arrays, I don't mind, but the fact is that the conventionnal notation in every paper, book or whatever is always substripting coordinates beginning with 1.
It may seem a quibble but the fact is that in formulas, it always takes a double-take to understand what we are taking about. Of course, this is much worst with matrices.
One obvious solution is just a slightly different overloading :
double& Vector::operator[](int i) {
return coordinates[i-1] ;
}
so I can type
double x1 = V[1];
V[2] = coord2;
It seems perfect except for one thing: this i-1 subtraction which seems a good candidate for a small overhead. Very small you would say, but I am doing computationnal mechanics, so this is typically something we couldn't afford.
So now (finally) my question: do you think a compiler can optimize this, or is there a way to make it optimize ? (templates, macro, pointer or reference kludge...)
Logically, in
double xi = V[i];
the integer between the bracket being a literal most of the time (except in 3-iteration for loops), inlining operator[] should make it possible, right ?
(sorry for this looong question)
EDIT:
Thanks for all your comments and answers
I kind of disagree with people telling me that we are used to 0-indexed vectors.
From an object-oriented perspective, I see no reason for a math Vector to be 0-indexed because implemented with a 0-indexed array. We're not suppose to care about the underlying implementation. Now, suppose I don't care about performance and use a map to implement Vector class. Then I would find it natural to map '1' with the '1st' coordinate.
That said I tried out with 1-indexed vectors and matrices, and after some code writing, I find it not interacting nicely every time I use an array around. I thougth Vector and containers (std::array,std::vector...) would not interact often (meaning, transfering data between one another), but it seems I was wrong.
Now I have of a solution that I think is less controversial (please give me your opinion) :
Every time I use a Vector in some physical context, I think of using an enum :
enum Coord {
x = 0,
y = 1,
z = 2
};
Vector V;
V[x] = 1;
The only disadvantage I see being that these x,y and z can be redefined without enven a warning...
This one should be measured or verified by looking at the disassembly, but my guess is: The getter function is tiny and its arguments are constant. There is a high chance the compiler will inline the function and constant-fold the subtraction. In that case the runtime cost would be zero.
Why not to try this:
class Vector {
public:
Vector(double x=0., double y=0., double z=0.) {
coordinates[1] = x;
coordinates[2] = y;
coordinates[3] = z;
}
private:
double coordinates[4];
};
If you are not instantiating your object in quantities of millions, then the memory waist might be affordable.
Have you actually profiled it or examined the generated code? That's how this question is answered.
If the operator[] implementation is visible then this is likely to be optimized to have zero overhead.
I recommend you define this in the header (.h) for your class. If you define it in the .cpp then the compiler can't optimize as much. Also, your index should not be an "int" which can have negative values... make it a size_t:
class Vector {
// ...
public:
double& operator[](const size_t i) {
return coordinates[i-1] ;
}
};
You cannot say anything objective about performance without benchmarking. On x86, this subtraction can be compiled using relative addressing, which is very cheap. If operator[] is inlined, then the overhead is zero—you can encourage this with inline or with compiler-specific instructions such as GCC’s __attribute__((always_inline)).
If you must guarantee it, and the offset is a compile-time constant, then using a template is the way to go:
template<size_t I>
double& Vector::get() {
return coordinates[i - 1];
}
double x = v.get<1>();
For all practical purposes, this is guaranteed to have zero overhead thanks to constant-folding. You could also use named accessors:
double Vector::x() const { return coordinates[0]; }
double Vector::y() const { return coordinates[1]; }
double Vector::z() const { return coordinates[2]; }
double& Vector::x() { return coordinates[0]; }
double& Vector::y() { return coordinates[1]; }
double& Vector::z() { return coordinates[2]; }
And for loops, iterators:
const double* Vector::begin() const { return coordinates; }
const double* Vector::end() const { return coordinates + 3; }
double* Vector::begin() { return coordinates; }
double* Vector::end() { return coordinates + 3; }
// (x, y, z) -> (x + 1, y + 1, z + 1)
for (auto& i : v) ++i;
Like many of the others here, however, I disagree with the premise of your question. You really should simply use 0-based indexing, as it is more natural in the realm of C++. The language is already very complex, and you need not complicate things further for those who will maintain your code in the future.
Seriously, benchmark this all three ways (ie, compare the subtraction and the double[4] methods to just using zero-based indices in the caller).
It's entirely possible you'll get a huge win from forcing 16-byte alignment on some cache architectures, and equally possible the subtraction is effectively free on some compiler/instruction set/code path combinations.
The only way to tell is to benchmark realistic code.