Be extremely careful using any of the other suggestions. It all depends on context.
I have spent a long time tracing a bugs in a system that presumed a==b
if |a-b|<epsilon
. The underlying problems were:
The implicit presumption in an algorithm that if a==b
and b==c
then a==c
.
Using the same epsilon for lines measured in inches and lines measured in mils (.001 inch). That is a==b
but 1000a!=1000b
. (This is why AlmostEqual2sComplement asks for the epsilon or max ULPS).
The use of the same epsilon for both the cosine of angles and the length of lines!
Using such a compare function to sort items in a collection. (In this case using the builtin C++ operator == for doubles produced correct results.)
Like I said: it all depends on context and the expected size of a
and b
.
BTW, std::numeric_limits<double>::epsilon()
is the "machine epsilon". It is the difference between 1.0 and the next value representable by a double. I guess that it could be used in the compare function but only if the expected values are less than 1. (This is in response to @cdv's answer...)
Also, if you basically have int
arithmetic in doubles
(here we use doubles to hold int values in certain cases) your arithmetic will be correct. For example 4.0/2.0 will be the same as 1.0+1.0. This is as long as you do not do things that result in fractions (4.0/3.0) or do not go outside of the size of an int.
For iterating backwards see this answer.
Iterating forwards is almost identical. Just change the iterators / swap decrement by increment. You should prefer iterators. Some people tell you to use std::size_t
as the index variable type. However, that is not portable. Always use the size_type
typedef of the container (While you could get away with only a conversion in the forward iterating case, it could actually go wrong all the way in the backward iterating case when using std::size_t
, in case std::size_t
is wider than what is the typedef of size_type
):
Using std::vector
Using iterators
for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
/* std::cout << *it; ... */
}
Important is, always use the prefix increment form for iterators whose definitions you don't know. That will ensure your code runs as generic as possible.
Using Range C++11
for(auto const& value: a) {
/* std::cout << value; ... */
Using indices
for(std::vector<int>::size_type i = 0; i != v.size(); i++) {
/* std::cout << v[i]; ... */
}
Using arrays
Using iterators
for(element_type* it = a; it != (a + (sizeof a / sizeof *a)); it++) {
/* std::cout << *it; ... */
}
Using Range C++11
for(auto const& value: a) {
/* std::cout << value; ... */
Using indices
for(std::size_t i = 0; i != (sizeof a / sizeof *a); i++) {
/* std::cout << a[i]; ... */
}
Read in the backward iterating answer what problem the sizeof
approach can yield to, though.
Best Answer
I would prefer
it - vec.begin()
precisely for the opposite reason given by Naveen: so it wouldn't compile if you change the vector into a list. If you do this during every iteration, you could easily end up turning an O(n) algorithm into an O(n^2) algorithm.Another option, if you don't jump around in the container during iteration, would be to keep the index as a second loop counter.
Note:
it
is a common name for a container iterator,std::container_type::iterator it;
.