getting avg of long and std::vector::size_type

A

Aaron

I'm trying to get an average of a long and a std::vector::size_type, but keep
getting 0 for some reason.

I've tried the following:

float avg = some_long / some_vec.size();
float avg = some_long / static_cast<long>(some_vec.size());

Both produce 0. Anyone able to give me a hint at what I'm doing wrong?
 
R

Rolf Magnus

Aaron said:
I'm trying to get an average of a long and a std::vector::size_type, but
keep getting 0 for some reason.

I've tried the following:

float avg = some_long / some_vec.size();
float avg = some_long / static_cast<long>(some_vec.size());

Both produce 0. Anyone able to give me a hint at what I'm doing wrong?

What you have here is an integer division, since both parameters are
integers. It doesn't have anything to do with averaging. As long as
some_long has a smaller value than some_vec.size(), avg will be 0. I'm not
sure what you really want. The average? Or just a floating point division?
 
A

Aaron

Rolf said:
Aaron wrote:




What you have here is an integer division, since both parameters are
integers. It doesn't have anything to do with averaging. As long as
some_long has a smaller value than some_vec.size(), avg will be 0. I'm not
sure what you really want. The average? Or just a floating point division?

Err maybe average was the wrong word (I blame it on not having my coffee yet
;p) Just floating point division.

I have a long value which is milliseconds that it took to process X elements in
the vector, so I need to store the result of milliseconds / vector size so that
I can say on average it took X milliseconds per element.
 
R

Rolf Magnus

Aaron said:
Err maybe average was the wrong word (I blame it on not having my coffee
yet ;p) Just floating point division.

I never understood this whole "coffee" thing. I don't drink any. ;-)
I have a long value which is milliseconds that it took to process X
elements in the vector, so I need to store the result of milliseconds /
vector size so that I can say on average it took X milliseconds per
element.

Ah, ok then. Try:

float avg = static_cast<float>(some_long) / some_vec.size();

As I said, the division type is chosen based on the two parameters. In your
case, both were integers, so you got an integer division. To make it a
floating point division, at least one parameter has to be of a floating
point type.
 
I

Ian McCulloch

Aaron said:
I'm trying to get an average of a long and a std::vector::size_type, but
keep getting 0 for some reason.

I've tried the following:

float avg = some_long / some_vec.size();
float avg = some_long / static_cast<long>(some_vec.size());

Both produce 0. Anyone able to give me a hint at what I'm doing wrong?

You have hit an unfortunate aspect of operator overloading. Your mother
probably told you it is very bad to abuse overloading by having one
operator performing different functions. What she should also have told
you is that the builtin operator/ is a prime example of such abuse.

If both arguments of operator/ are integral types, then it means integral
division, and the result is truncated to an integer. If one or both of the
arguments is a floating-point type then it means instead ordinary real
division. Try

float avg = float(some_long) / some_vec.size();

HTH,
Ian McCulloch
 
O

Old Wolf

Aaron said:
Try:

float avg = static_cast<float>(some_long) / some_vec.size();

'double' is almost always a better choice than 'float'. You
get a lot more accuracy with no penalty.
Even if you write:

float avg = static_cast<double>(some_long) / some_vec.size();

then avg may be more accurate than the original example.
 
E

eed132

Rolf Magnus already told you what you need to do, I just thought I'd
add a clarification point.

C and C++ just look at and evaluate one part of an expression at a
time. It evaluates that, then moves to the next operation. In the code:
int a, b;
float c = a/b;
the compiler starts by evaluating a/b. The only information it pays
attention to at this stage is what is in 'a/b'. It sees that a is an
int and b is an int, so it performs integer division on a and b. (This
gives 0 is a < b since it truncates -- rounds down -- any decimal
portion.) Only after getting this (integer) result does it convert it
to a floating point number and store it in c.

Rolf's fix, 'float c = static_cast<float>(a) / b', changes the
evaluation sequence. Now the compiler starts with the cast. So the
first step is to convert a to a float. Then it looks at the division.
Now the division is a float divided by an integer. In this case, the
C/C++ rules tell it to promote the integer to a float and do floating
point division, which is then stored in c. This gives the right answer.
(But again, I would reccomend taking Old Wolf's advice and using
double.)

One more, this time more complicated example:
int a, b, c;
int d = (a / b) / (static_cast<float>(c));
The sequence of evaulation is:
1. The compiler looks at 'a/b' and does integer division since both
operands are ints (call this intermediate result r1)
2. The compiler looks at 'static_cast<float>(c)' and performs the cast
(call this converted value r2)
3. The compiler looks at r1/r2. r1 is an int and r2 is a float, so it
converts r1 to a float and does floating point division. (call the
quotient r3)
4. Finally, the compiler looks at the assignment d = r3. d is an int,
so it demotes r3 to an integer and stores the value.

(Actually, as a technical note, I think the standard leaves the order
of steps 1 and 3 undefined, so the compiler could do it either way. I'm
not positive about that, but I think that's the way it is.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,439
Members
44,829
Latest member
PIXThurman

Latest Threads

Top