469,271 Members | 1,023 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,271 developers. It's quick & easy.

min and max running values

Hi

often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
int lLimit = 999999999999; //hoping the compiler will not complain

uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;

how do I choose the original lLimit?
is there more cleaver way?

thanks
Mar 5 '07 #1
41 2526
Gary Wessle wrote:
Hi

often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
'int' can be negative, you know...
int lLimit = 999999999999; //hoping the compiler will not complain
Why not just

int lLimit = INT_MAX; // or use std::numeric_limits<int>::max

?
>
uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;

how do I choose the original lLimit?
is there more cleaver way?
Clever? I don't know. Reliable more like it.

V
-
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 5 '07 #2
On 2007-03-05 10:22:49 -0800, Gary Wessle <ph****@yahoo.comsaid:
Hi

often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
What about negative values?
int lLimit = 999999999999; //hoping the compiler will not complain
Why "hope"? Why not just get the value right to begin with?
>
uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;

how do I choose the original lLimit?
#include <limits>
#include <algorithm>

....

int uLimit = std::numeric_limits<int>::min();
int lLimit = std::numeric_limits<int>::max();

uLimit = std::max(val_read, uLimit);
lLimit = std::min(val_read, uLimit);
is there more cleaver way?

thanks

--
Clark S. Cox III
cl*******@gmail.com

Mar 5 '07 #3
how do I choose the original lLimit?
is there more cleaver way?
use std::numeric_limits<int>::max() and
std::numeric_limits<int>::min().

Mar 5 '07 #4
Gary Wessle wrote:
Hi

often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
int lLimit = 999999999999; //hoping the compiler will not complain

uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;

how do I choose the original lLimit?
Use the first value of val_read for both limits.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 5 '07 #5
On 2007-03-05 15:31:29 -0800, Pete Becker <pe**@versatilecoding.comsaid:
Gary Wessle wrote:
>Hi

often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
int lLimit = 999999999999; //hoping the compiler will not complain

uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;

how do I choose the original lLimit?

Use the first value of val_read for both limits.
I would tend to disagree, as that would require a special case for the
first iteration of the loop.

i.e. I would prefer A to B:

/*A*/
int maxValue = std::numeric_limits<int>::min();
int minValue = std::numeric_limits<int>::max();

while( ... )
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);

...
}

/*B*/
int input = getNextValue();
int maxValue = input;
int minValue = input;

do
{
input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
}
while(...);

--
Clark S. Cox III
cl*******@gmail.com

Mar 6 '07 #6
Clark Cox wrote:
On 2007-03-05 15:31:29 -0800, Pete Becker <pe**@versatilecoding.comsaid:
>Gary Wessle wrote:
>>Hi

often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
int lLimit = 999999999999; //hoping the compiler will not complain

uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;

how do I choose the original lLimit?

Use the first value of val_read for both limits.

I would tend to disagree, as that would require a special case for the
first iteration of the loop.

i.e. I would prefer A to B:
Err, they do two different things. And, of course, they're written to
make A look better.
/*A*/
int maxValue = std::numeric_limits<int>::min();
int minValue = std::numeric_limits<int>::max();

while( ... )
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);

...
}

/*B*/
int input = getNextValue();
int maxValue = input;
int minValue = input;

do
{
input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
}
while(...);
Let me present two versions that are biased the other way:

/*A*/
maxValue = std::numeric_limits<int>::min();
minValue = std::numeric_limits<int>::max();

while (...)
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
....
}

/*B*/
maxValue = minValue = getNextValue();

while (...)
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
....
}

Obviously B is vastly superior to the wordy, verbose, lengthy,
overwrought, wordy, redundant, and repetitive A. <g>

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #7
On Mar 5, 5:33 pm, Pete Becker <p...@versatilecoding.comwrote:
Clark Cox wrote:
On 2007-03-05 15:31:29 -0800, Pete Becker <p...@versatilecoding.comsaid:
Gary Wessle wrote:
Hi
>often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
int lLimit = 999999999999; //hoping the compiler will not complain
>uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;
>how do I choose the original lLimit?
Use the first value of val_read for both limits.
I would tend to disagree, as that would require a special case for the
first iteration of the loop.
i.e. I would prefer A to B:

Err, they do two different things. And, of course, they're written to
make A look better.
/*A*/
int maxValue = std::numeric_limits<int>::min();
int minValue = std::numeric_limits<int>::max();
while( ... )
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
...
}
/*B*/
int input = getNextValue();
int maxValue = input;
int minValue = input;
do
{
input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
}
while(...);

Let me present two versions that are biased the other way:

/*A*/
maxValue = std::numeric_limits<int>::min();
minValue = std::numeric_limits<int>::max();

while (...)
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
...

}

/*B*/
maxValue = minValue = getNextValue();

while (...)
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
...

}

Obviously B is vastly superior to the wordy, verbose, lengthy,
overwrought, wordy, redundant, and repetitive A. <g>
Even with this rewrite, I would still prefer A. I'd prefer not to do
the same thing in the loop setup as I do each iteration of the loop
(which was my main point; poorly stated as it was :) ). If all the
real code does is find the minimum and maximum then the difference is
trivial, but if something else needs to be done with the input then it
will have to be repeated; once in the loop's setup, and once in the
body of the loop.

Mar 6 '07 #8
Clark Cox wrote:
On 2007-03-05 15:31:29 -0800, Pete Becker <pe**@versatilecoding.comsaid:
>Gary Wessle wrote:
>>Hi

often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
int lLimit = 999999999999; //hoping the compiler will not complain

uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;

how do I choose the original lLimit?


Use the first value of val_read for both limits.


I would tend to disagree, as that would require a special case for the
first iteration of the loop.
But there _is_ a special condition for the first value - namely that
there be one! You cannot have a well-defined max or min of zero items.
So read the first value, check that you can get that first value and
complain somehow (err message, exception, etc.) if you can't, then make
it the starting running value for both max and min, and then have a loop
for any remaining values. That is the only way that is consistent with
the concept of what a max or a min actually is. Picking some hocum
'safe' starting value, even the min or max allowable value for the data
type, will give a broken answer (an answer claiming to be correct, but
which isn't) when there are no input items.

--
Ron House ho***@usq.edu.au
http://www.sci.usq.edu.au/staff/house
Ethics website: http://www.sci.usq.edu.au/staff/house/goodness
Mar 6 '07 #9
cl*******@gmail.com wrote:
On Mar 5, 5:33 pm, Pete Becker <p...@versatilecoding.comwrote:
>Clark Cox wrote:
>>On 2007-03-05 15:31:29 -0800, Pete Becker <p...@versatilecoding.comsaid:
Gary Wessle wrote:
Hi
often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
int lLimit = 999999999999; //hoping the compiler will not complain
uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;
how do I choose the original lLimit?
Use the first value of val_read for both limits.
I would tend to disagree, as that would require a special case for the
first iteration of the loop.
i.e. I would prefer A to B:
Err, they do two different things. And, of course, they're written to
make A look better.
>>/*A*/
int maxValue = std::numeric_limits<int>::min();
int minValue = std::numeric_limits<int>::max();
while( ... )
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
...
}
/*B*/
int input = getNextValue();
int maxValue = input;
int minValue = input;
do
{
input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
}
while(...);
Let me present two versions that are biased the other way:

/*A*/
maxValue = std::numeric_limits<int>::min();
minValue = std::numeric_limits<int>::max();

while (...)
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
...

}

/*B*/
maxValue = minValue = getNextValue();

while (...)
{
int input = getNextValue();
maxValue = std::max(maxValue, input);
minValue = std::min(minValue, input);
...

}

Obviously B is vastly superior to the wordy, verbose, lengthy,
overwrought, wordy, redundant, and repetitive A. <g>

Even with this rewrite, I would still prefer A. I'd prefer not to do
the same thing in the loop setup as I do each iteration of the loop
(which was my main point; poorly stated as it was :) ). If all the
real code does is find the minimum and maximum then the difference is
trivial, but if something else needs to be done with the input then it
will have to be repeated; once in the loop's setup, and once in the
body of the loop.
But all that was asked for was to find the minimum or the maximum, so
the possibility that one approach may be better than another in some
other situation isn't particularly pertinent. I'm really not interested
in generating a tutorial on when to do what, just in suggesting possible
approaches.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #10
Ron House wrote:
Clark Cox wrote:
>On 2007-03-05 15:31:29 -0800, Pete Becker <pe**@versatilecoding.com>
said:
>>Gary Wessle wrote:

Hi

often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
int lLimit = 999999999999; //hoping the compiler will not complain

uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;

how do I choose the original lLimit?
Use the first value of val_read for both limits.


I would tend to disagree, as that would require a special case for
the first iteration of the loop.

But there _is_ a special condition for the first value - namely that
there be one! You cannot have a well-defined max or min of zero items.
Why not? The sheer fact that min max should tell you that there were
no items read. Am I missing something?
So read the first value, check that you can get that first value and
complain somehow (err message, exception, etc.) if you can't,
If you can't what? Complain? Read? Check?
then
make it the starting running value for both max and min, and then
have a loop for any remaining values. That is the only way that is
consistent with the concept of what a max or a min actually is.
Huh?
Picking some hocum 'safe' starting value, even the min or max
allowable value for the data type, will give a broken answer (an
answer claiming to be correct, but which isn't) when there are no
input items.
No, it won't. See above.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 6 '07 #11
Victor Bazarov wrote:
Ron House wrote:
>But there _is_ a special condition for the first value - namely that
there be one! You cannot have a well-defined max or min of zero items.

Why not? The sheer fact that min max should tell you that there were
no items read. Am I missing something?
The original request was not for a function that computes both min and
max, but was a general question about how to calculate them. Yes, if
you're doing both, you can use this hack. But it's not part of a general
solution for picking an initial value.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #12
On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:
Clark Cox wrote:
>On 2007-03-05 15:31:29 -0800, Pete Becker <pe**@versatilecoding.comsaid:
>>Gary Wessle wrote:

Hi

often I need to read numbers and only keep the highest or lowest.
so I do something like
int uLimit = 0;
int lLimit = 999999999999; //hoping the compiler will not complain

uLimit = val_read uLimit ? val_read : uLimit;
lLimit = val_read < lLimit ? val_read : lLimit;

how do I choose the original lLimit?
Use the first value of val_read for both limits.


I would tend to disagree, as that would require a special case for the
first iteration of the loop.

But there _is_ a special condition for the first value - namely that
there be one!
Who says that that is a necessery condition?
You cannot have a well-defined max or min of zero items. So read the
first value, check that you can get that first value and complain
somehow (err message, exception, etc.)
OK, so you check for error on reading the first value; do you then do
zero error checking on the second and subsequent values? No, you
*repeat the same error checking* (or a subset thereof); leading to
redundant code, which adds unneeded complexity and increases the
maintainence burden.
if you can't, then make it the starting running value for both max and
min, and then have a loop for any remaining values. That is the only
way that is consistent with the concept of what a max or a min actually
is. Picking some hocum 'safe' starting value, even the min or max
allowable value for the data type, will give a broken answer (an answer
claiming to be correct, but which isn't) when there are no input items.
No it won't, if min max, then there obviously werent any input
values. That doesn't sound like a broken answer to me. It sounds like
a clearly identifiable error condition that leaves no room for
ambiguity.

--
Clark S. Cox III
cl*******@gmail.com

Mar 6 '07 #13
Clark Cox wrote:
On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:
>You cannot have a well-defined max or min of zero items. So read the
first value, check that you can get that first value and complain
somehow (err message, exception, etc.)

OK, so you check for error on reading the first value; do you then do
zero error checking on the second and subsequent values? No, you *repeat
the same error checking* (or a subset thereof); leading to redundant
code, which adds unneeded complexity and increases the maintainence burden.
Maybe. But it's also reasonable to simply say that calling a function
that returns the minimum value in a range of values with an empty range
produces undefined behavior. Implementations can check if they want to,
but aren't required to do anything sensible. After all, asking for the
minimum of no values is not a sensible request.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #14
Pete Becker wrote:
Clark Cox wrote:
>On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:
>>You cannot have a well-defined max or min of zero items. So read the
first value, check that you can get that first value and complain
somehow (err message, exception, etc.)

OK, so you check for error on reading the first value; do you then do
zero error checking on the second and subsequent values? No, you *repeat
the same error checking* (or a subset thereof); leading to redundant
code, which adds unneeded complexity and increases the maintainence
burden.

Maybe. But it's also reasonable to simply say that calling a function
that returns the minimum value in a range of values with an empty range
produces undefined behavior. Implementations can check if they want to,
but aren't required to do anything sensible. After all, asking for the
minimum of no values is not a sensible request.
There is nothing non-sensible about defining the value of an associative
operation for an empty range of operands; in fact, it makes life much
easier, and we do it all the time for operations like + and *. The
convention, stolen from mathematics, is always that an associative
operation applied to an empty list of operands yields the identity element
with respect to the operation:

empty sum = 0 (this yields the meaning of a*0 = 0)
empty product = 1 (this yields the meaning of a^0 = 1)
empty union = empty_set
empty intersection = all class (or some problem specific universal set)

The convention ensures that the splitting

sum{ index in [a,b) } + sum{ index in [b,c) } = sum{ index in [a,c) }

holds even if a=b or b=c.

Therefore, it is quite natural to define

empty max = minimum possible value
empty min = maximum possible value

if you are in a situation where a minimum/maximum possible value exits.
Best

Kai-Uwe Bux
Mar 6 '07 #15
On 2007-03-06 09:08:27 -0800, Pete Becker <pe**@versatilecoding.comsaid:
Clark Cox wrote:
>On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:
>>You cannot have a well-defined max or min of zero items. So read the
first value, check that you can get that first value and complain
somehow (err message, exception, etc.)

OK, so you check for error on reading the first value; do you then do
zero error checking on the second and subsequent values? No, you
*repeat the same error checking* (or a subset thereof); leading to
redundant code, which adds unneeded complexity and increases the
maintainence burden.

Maybe. But it's also reasonable to simply say that calling a function
that returns the minimum value in a range of values with an empty range
produces undefined behavior. Implementations can check if they want to,
but aren't required to do anything sensible. After all, asking for the
minimum of no values is not a sensible request.
std::min_element seems to think that it is a perfectly sensible
request, with a well-defined return value.

--
Clark S. Cox III
cl*******@gmail.com

Mar 6 '07 #16
Kai-Uwe Bux wrote:
>
Therefore, it is quite natural to define

empty max = minimum possible value
empty min = maximum possible value

if you are in a situation where a minimum/maximum possible value exits.
Sure3, if that's what the application's design requires. But since we
don't have a design specification, it's not possible to choose the most
appropriate approach.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #17
Clark Cox wrote:
On 2007-03-06 09:08:27 -0800, Pete Becker <pe**@versatilecoding.comsaid:
>Clark Cox wrote:
>>On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:

You cannot have a well-defined max or min of zero items. So read the
first value, check that you can get that first value and complain
somehow (err message, exception, etc.)

OK, so you check for error on reading the first value; do you then do
zero error checking on the second and subsequent values? No, you
*repeat the same error checking* (or a subset thereof); leading to
redundant code, which adds unneeded complexity and increases the
maintainence burden.

Maybe. But it's also reasonable to simply say that calling a function
that returns the minimum value in a range of values with an empty
range produces undefined behavior. Implementations can check if they
want to, but aren't required to do anything sensible. After all,
asking for the minimum of no values is not a sensible request.

std::min_element seems to think that it is a perfectly sensible request,
with a well-defined return value.
Yes, because min_element takes iterators and follows the conventions of
STL algorithms. There are other ways to design functions, and in the
absence of any requirements, it's not possible to decide whether one
approach is better than another.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #18
Clark Cox wrote:
On 2007-03-06 09:08:27 -0800, Pete Becker <pe**@versatilecoding.comsaid:
>Clark Cox wrote:
>>On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:

You cannot have a well-defined max or min of zero items. So read the
first value, check that you can get that first value and complain
somehow (err message, exception, etc.)

OK, so you check for error on reading the first value; do you then do
zero error checking on the second and subsequent values? No, you
*repeat the same error checking* (or a subset thereof); leading to
redundant code, which adds unneeded complexity and increases the
maintainence burden.

Maybe. But it's also reasonable to simply say that calling a function
that returns the minimum value in a range of values with an empty
range produces undefined behavior. Implementations can check if they
want to, but aren't required to do anything sensible. After all,
asking for the minimum of no values is not a sensible request.

std::min_element seems to think that it is a perfectly sensible request,
with a well-defined return value.
Of course. And the return value is an iterator that tells you there is
no minimum, not an artificially created "minimum" value.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #19
Clark Cox wrote:
>
std::min_element seems to think that it is a perfectly sensible request,
with a well-defined return value.
Okay, third reply to this message. <gstd::min_element is a good
example of a context where the most straightforward implementation
doesn't use an artificial minimum value. Here's how it's most naturally
implemented (using int* instead of iterators, to simplify some of the
code in irrelevant ways):

int *min_element(int *first, int *last)
{
if (first == last)
return last;
int *val = first++;
while (first != last)
{
if (*first < *val)
val = first;
++first;
}
return val;
}

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #20
Pete Becker wrote:
Kai-Uwe Bux wrote:
>>
Therefore, it is quite natural to define

empty max = minimum possible value
empty min = maximum possible value

if you are in a situation where a minimum/maximum possible value exits.

Sure3, if that's what the application's design requires. But since we
don't have a design specification, it's not possible to choose the most
appropriate approach.
You are misunderstanding my point. What I argued is actually quite
independent of any particular application. I maintain that the definitions
above are _natural_ and not arbitrary as they may seem at first glance.
Insofar as your criticism of the implementation proposed up-thread is based
upon the assumption that the implementation uses arbitrary, unmotivated
magic numbers, it is ill-founded. Quite contrary, the proposed return
values for an empty sequence are perfectly natural. They have exactly the
properties that one should expect. Moreover, no other possible return value
has those properties.

You are, however, right that it may depend on the specifics of the
application, whether an implementation with undefined behavior could have
an advantage compared to an implementation based upon the above proposal
(e.g., performance-wise). On the other hand, I doubt that I will see an
application where the undefined behavior solution is superior any time
soon.
Best

Kai-Uwe Bux
Mar 6 '07 #21
On 2007-03-06 11:20:05 -0800, Pete Becker <pe**@versatilecoding.comsaid:
Clark Cox wrote:
>On 2007-03-06 09:08:27 -0800, Pete Becker <pe**@versatilecoding.comsaid:
>>Clark Cox wrote:
On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:

You cannot have a well-defined max or min of zero items. So read the
first value, check that you can get that first value and complain
somehow (err message, exception, etc.)

OK, so you check for error on reading the first value; do you then do
zero error checking on the second and subsequent values? No, you
*repeat the same error checking* (or a subset thereof); leading to
redundant code, which adds unneeded complexity and increases the
maintainence burden.
Maybe. But it's also reasonable to simply say that calling a function
that returns the minimum value in a range of values with an empty range
produces undefined behavior. Implementations can check if they want to,
but aren't required to do anything sensible. After all, asking for the
minimum of no values is not a sensible request.

std::min_element seems to think that it is a perfectly sensible
request, with a well-defined return value.

Yes, because min_element takes iterators and follows the conventions of
STL algorithms. There are other ways to design functions, and in the
absence of any requirements, it's not possible to decide whether one
approach is better than another.
Indeed, so saying that "asking for the minimum of no values is not a
sensible request" isn't sensible ;)
--
Clark S. Cox III
cl*******@gmail.com

Mar 6 '07 #22
Kai-Uwe Bux wrote:
>
You are misunderstanding my point. What I argued is actually quite
independent of any particular application. I maintain that the definitions
above are _natural_ and not arbitrary as they may seem at first glance.
You are putting words in my mouth. I didn't say they were arbitrary,
just that they weren't necessarily the best possible solution for all cases.
Insofar as your criticism of the implementation proposed up-thread is based
upon the assumption that the implementation uses arbitrary, unmotivated
magic numbers, it is ill-founded. Quite contrary, the proposed return
values for an empty sequence are perfectly natural. They have exactly the
properties that one should expect. Moreover, no other possible return value
has those properties.

You are, however, right that it may depend on the specifics of the
application, whether an implementation with undefined behavior could have
an advantage compared to an implementation based upon the above proposal
(e.g., performance-wise). On the other hand, I doubt that I will see an
application where the undefined behavior solution is superior any time
soon.
You are misunderstanding my point, which was about designing in a
vacuum. Don't do it. If you don't know exactly what the requirements
are, you cannot choose among various possible solutions. So the
assertion that my original suggestion was somehow inferior or misguided
has no sound basis.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #23
Clark Cox wrote:
On 2007-03-06 11:20:05 -0800, Pete Becker <pe**@versatilecoding.comsaid:
>Clark Cox wrote:
>>On 2007-03-06 09:08:27 -0800, Pete Becker <pe**@versatilecoding.com>
said:

Clark Cox wrote:
On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:
>
>You cannot have a well-defined max or min of zero items. So read
>the first value, check that you can get that first value and
>complain somehow (err message, exception, etc.)
>
OK, so you check for error on reading the first value; do you then
do zero error checking on the second and subsequent values? No, you
*repeat the same error checking* (or a subset thereof); leading to
redundant code, which adds unneeded complexity and increases the
maintainence burden.
>

Maybe. But it's also reasonable to simply say that calling a
function that returns the minimum value in a range of values with an
empty range produces undefined behavior. Implementations can check
if they want to, but aren't required to do anything sensible. After
all, asking for the minimum of no values is not a sensible request.

std::min_element seems to think that it is a perfectly sensible
request, with a well-defined return value.

Yes, because min_element takes iterators and follows the conventions
of STL algorithms. There are other ways to design functions, and in
the absence of any requirements, it's not possible to decide whether
one approach is better than another.

Indeed, so saying that "asking for the minimum of no values is not a
sensible request" isn't sensible ;)
It depends on the context, a concept that seems to be hard for most
participants in this thread to grasp.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 6 '07 #24
Pete Becker wrote:
Clark Cox wrote:
>On 2007-03-06 11:20:05 -0800, Pete Becker <pe**@versatilecoding.com>
said:
>>Clark Cox wrote:
On 2007-03-06 09:08:27 -0800, Pete Becker <pe**@versatilecoding.com>
said:

Clark Cox wrote:
>On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:
>>
>>You cannot have a well-defined max or min of zero items. So read
>>the first value, check that you can get that first value and
>>complain somehow (err message, exception, etc.)
>>
>OK, so you check for error on reading the first value; do you then
>do zero error checking on the second and subsequent values? No, you
>*repeat the same error checking* (or a subset thereof); leading to
>redundant code, which adds unneeded complexity and increases the
>maintainence burden.
>>
>
Maybe. But it's also reasonable to simply say that calling a
function that returns the minimum value in a range of values with an
empty range produces undefined behavior. Implementations can check
if they want to, but aren't required to do anything sensible. After
all, asking for the minimum of no values is not a sensible request.

std::min_element seems to think that it is a perfectly sensible
request, with a well-defined return value.
Yes, because min_element takes iterators and follows the conventions
of STL algorithms. There are other ways to design functions, and in
the absence of any requirements, it's not possible to decide whether
one approach is better than another.

Indeed, so saying that "asking for the minimum of no values is not a
sensible request" isn't sensible ;)

It depends on the context, a concept that seems to be hard for most
participants in this thread to grasp.
Where is the context qualification in your statement:
After all, asking for the minimum of no values is not a sensible request.
Your statement did not read:

asking for the minimum of no values is not always a sensible request.
Best

Kai-Uwe Bux
Mar 6 '07 #25
Pete Becker wrote:
Kai-Uwe Bux wrote:
>>
You are misunderstanding my point. What I argued is actually quite
independent of any particular application. I maintain that the
definitions above are _natural_ and not arbitrary as they may seem at
first glance.

You are putting words in my mouth. I didn't say they were arbitrary,
just that they weren't necessarily the best possible solution for all
cases.
You said they are "artificial":
std::min_element is a good example of a context where the most
straightforward implementation doesn't use an artificial minimum value.
(elsethread, contrasting std::min_element with the proposed implementation
up-thread)
Best

Kai-Uwe Bux
Mar 6 '07 #26
Kai-Uwe Bux wrote:
Pete Becker wrote:
>Kai-Uwe Bux wrote:
>>You are misunderstanding my point. What I argued is actually quite
independent of any particular application. I maintain that the
definitions above are _natural_ and not arbitrary as they may seem at
first glance.
You are putting words in my mouth. I didn't say they were arbitrary,
just that they weren't necessarily the best possible solution for all
cases.

You said they are "artificial":
Yes. "Artificial" is not "arbitrary".

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 7 '07 #27
Kai-Uwe Bux wrote:
Pete Becker wrote:
>Clark Cox wrote:
>>On 2007-03-06 11:20:05 -0800, Pete Becker <pe**@versatilecoding.com>
said:

Clark Cox wrote:
On 2007-03-06 09:08:27 -0800, Pete Becker <pe**@versatilecoding.com>
said:
>
>Clark Cox wrote:
>>On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:
>>>
>>>You cannot have a well-defined max or min of zero items. So read
>>>the first value, check that you can get that first value and
>>>complain somehow (err message, exception, etc.)
>>OK, so you check for error on reading the first value; do you then
>>do zero error checking on the second and subsequent values? No, you
>>*repeat the same error checking* (or a subset thereof); leading to
>>redundant code, which adds unneeded complexity and increases the
>>maintainence burden.
>>>
>Maybe. But it's also reasonable to simply say that calling a
>function that returns the minimum value in a range of values with an
>empty range produces undefined behavior. Implementations can check
>if they want to, but aren't required to do anything sensible. After
>all, asking for the minimum of no values is not a sensible request.
std::min_element seems to think that it is a perfectly sensible
request, with a well-defined return value.
>
Yes, because min_element takes iterators and follows the conventions
of STL algorithms. There are other ways to design functions, and in
the absence of any requirements, it's not possible to decide whether
one approach is better than another.
Indeed, so saying that "asking for the minimum of no values is not a
sensible request" isn't sensible ;)
It depends on the context, a concept that seems to be hard for most
participants in this thread to grasp.

Where is the context qualification in your statement:
>After all, asking for the minimum of no values is not a sensible request.

Your statement did not read:

asking for the minimum of no values is not always a sensible request.
Sigh. The context was all of the quoted material.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 7 '07 #28
Pete Becker wrote:
Kai-Uwe Bux wrote:
>Pete Becker wrote:
>>Kai-Uwe Bux wrote:
You are misunderstanding my point. What I argued is actually quite
independent of any particular application. I maintain that the
definitions above are _natural_ and not arbitrary as they may seem at
first glance.
You are putting words in my mouth. I didn't say they were arbitrary,
just that they weren't necessarily the best possible solution for all
cases.

You said they are "artificial":

Yes. "Artificial" is not "arbitrary".
True, and your point is taken.

However, "artificial" is the opposite of "natural". I argued there are
natural return values for these cases. If you consider them artificial,
then that still is a point of disagreement.
Best

Kai-Uwe Bux
Mar 7 '07 #29
Pete Becker wrote:
Kai-Uwe Bux wrote:
>Pete Becker wrote:
>>Clark Cox wrote:
On 2007-03-06 11:20:05 -0800, Pete Becker <pe**@versatilecoding.com>
said:

Clark Cox wrote:
>On 2007-03-06 09:08:27 -0800, Pete Becker <pe**@versatilecoding.com>
>said:
>>
>>Clark Cox wrote:
>>>On 2007-03-05 20:08:44 -0800, Ron House <ho***@usq.edu.ausaid:
>>>>
>>>>You cannot have a well-defined max or min of zero items. So read
>>>>the first value, check that you can get that first value and
>>>>complain somehow (err message, exception, etc.)
>>>OK, so you check for error on reading the first value; do you then
>>>do zero error checking on the second and subsequent values? No, you
>>>*repeat the same error checking* (or a subset thereof); leading to
>>>redundant code, which adds unneeded complexity and increases the
>>>maintainence burden.
>>>>
>>Maybe. But it's also reasonable to simply say that calling a
>>function that returns the minimum value in a range of values with an
>>empty range produces undefined behavior. Implementations can check
>>if they want to, but aren't required to do anything sensible. After
>>all, asking for the minimum of no values is not a sensible request.
>std::min_element seems to think that it is a perfectly sensible
>request, with a well-defined return value.
>>
Yes, because min_element takes iterators and follows the conventions
of STL algorithms. There are other ways to design functions, and in
the absence of any requirements, it's not possible to decide whether
one approach is better than another.
Indeed, so saying that "asking for the minimum of no values is not a
sensible request" isn't sensible ;)

It depends on the context, a concept that seems to be hard for most
participants in this thread to grasp.

Where is the context qualification in your statement:
>>After all, asking for the minimum of no values is not a sensible
request.

Your statement did not read:

asking for the minimum of no values is not always a sensible request.

Sigh. The context was all of the quoted material.
I feel, now you are using the word "context" in two different meanings:

(a) in the line

"It depends on the context, a concept that seems to be hard for most
participants in this thread to grasp."

I understood you to refer to the particular target application.

(b) In the line

"The context was all of the quoted material."

you seem to refer to the context of your statement within this thread.

Should I have misunderstood you, I apologize.
In any case, I still don't buy your claim that "asking for the minimum of no
values is not a sensible request." I don't see that the context of the
quoted material provided any reason to interpret that statement as a modest
claim that _sometimes_ asking for such a value is not sensible. I still
think the only possible reading is that such a request is _never_ sensible.
If you meant the former you could have saved a lot of bandwith if you had
qualified the claim accordingly.

To me, it appears that you started with strong, unqualified, and quite
general statements:

But it's also reasonable to simply say that calling a
function that returns the minimum value in a range of values with an
empty range produces undefined behavior.

Note that this does _not: say "depending on the application, it may also be
reasonable to simply say ...". Instead it makes a quite general statement
that simply introducing undefined behavior for this case is also a
reasonable option. Since the claim is not further qualified, the standard
interpretation is that this option is always or at least generally
reasonable. The rational for this advice is also worded quite general:

After all, asking for the minimum of no values is not a sensible request.

Again, no restrictions are mentioned. So, we still have no reason to
interpret these statements in a weak or restricted way.

Later, you reverted to the position that all depends on the specs of the
particular application. That is quite different from how you started and
does not provide any justification for the claims you actually made. It
argues much weaker claims (essentially it argues existence statements where
universal statements were made). Maybe, I am misreading your claims, but I
feel its just the way they are worded that makes me read them the way I do.
Best

Kai-Uwe Bux
Mar 7 '07 #30
Kai-Uwe Bux wrote:
>
However, "artificial" is the opposite of "natural". I argued there are
natural return values for these cases.
With such a return value, how does the caller distinguish between a
value that means that there were no elements, and the same value being
the actual minimum?

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 7 '07 #31
Pete Becker wrote:
Kai-Uwe Bux wrote:
>>
However, "artificial" is the opposite of "natural". I argued there
are natural return values for these cases.

With such a return value, how does the caller distinguish between a
value that means that there were no elements, and the same value being
the actual minimum?
When a single value is returned, there is no way. When two values are
expected (however it's done), it's easy to judge: min max. *If* the
search for min and max is wrapped into a function, we can discuss the
design of that function, if you'd like.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 7 '07 #32
Victor Bazarov wrote:
Pete Becker wrote:
>Kai-Uwe Bux wrote:
>>However, "artificial" is the opposite of "natural". I argued there
are natural return values for these cases.
With such a return value, how does the caller distinguish between a
value that means that there were no elements, and the same value being
the actual minimum?

When a single value is returned, there is no way. When two values are
expected (however it's done), it's easy to judge: min max. *If* the
search for min and max is wrapped into a function, we can discuss the
design of that function, if you'd like.
No, thanks, I understand it quite well. But it wasn't the original
question, despite having far too many words devoted to it.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 7 '07 #33
Kai-Uwe Bux wrote:
>
However, "artificial" is the opposite of "natural". I argued there are
natural return values for these cases. If you consider them artificial,
then that still is a point of disagreement.
"Natural" means "existing in or caused by nature; not made or caused by
humankind." Isn't numeric_limits<int>::min() made by humankind? Or are
we both using words a bit loosely, in order to convey meaning more clearly?

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 7 '07 #34
Pete Becker wrote:
Kai-Uwe Bux wrote:
>>
However, "artificial" is the opposite of "natural". I argued there are
natural return values for these cases.

With such a return value, how does the caller distinguish between a
value that means that there were no elements, and the same value being
the actual minimum?
For an empty sequence, the returned value _is_ the _actual minimum_ (by the
proposed definition), in the very same way that 0 is the actual value of an
empty sum and 1 is the actual value of an empty product.

In general, the minimum of a sequence does not tell you anything about its
length. Why would you expect/want it to tell you that the sequence was
non-empty? _If_ the caller wants to know whether an empty sequence was
passed, the caller can check that by comparing the two iterators defining
the range (assuming that the signature reads something like:

template < typename IntIter >
int min_value ( IntIter from, IntIter to );

A difference between an implementation that introduces undefined behavior
for from==to and an implementation that does not is that the former
requires you to (a) always check unless you can prove from!=to and (b)
perform the check before the call. An implementation not introducing
undefined behavior allows you to skip the check in cases you don't need to
care whether the range is empty (a natural return value may very well
eliminate the necessity for such a check), and even if you need to know you
can check after the call to min_value at your convenience.
Best

Kai-Uwe Bux
Mar 7 '07 #35
Kai-Uwe Bux wrote:
Pete Becker wrote:
>Kai-Uwe Bux wrote:
>>However, "artificial" is the opposite of "natural". I argued there are
natural return values for these cases.
With such a return value, how does the caller distinguish between a
value that means that there were no elements, and the same value being
the actual minimum?

For an empty sequence, the returned value _is_ the _actual minimum_ (by the
proposed definition), in the very same way that 0 is the actual value of an
empty sum and 1 is the actual value of an empty product.
No, they're not the same. The sum and the product of a sequence are
statements about the cumulative effect of an operation. The minimum
value in a set is a statement about a particular value, and if that
value isn't present in the set then there's something mighty fishy about
calling it the minimum value.
In general, the minimum of a sequence does not tell you anything about its
length. Why would you expect/want it to tell you that the sequence was
non-empty?
I don't want it to. Asking for the minimum value of an empty sequence is
meaningless, and returning a value that masquerades as an element of
that sequence doesn't make it meaningful. If you've got a set<intand
you look for its minimum value, you ought to be able to find that value
in the set. That's not the case for sum and product.

_If_ the caller wants to know whether an empty sequence was
passed, the caller can check that by comparing the two iterators defining
the range (assuming that the signature reads something like:

template < typename IntIter >
int min_value ( IntIter from, IntIter to );
Or, even better, don't pretend that there's a value. Do what min_range
does, and return an iterator to the value, with end-of-sequence
designating that there was no minimum (i.e. the sequence was empty).

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 7 '07 #36
Pete Becker wrote:
Kai-Uwe Bux wrote:
>Pete Becker wrote:
>>Kai-Uwe Bux wrote:
However, "artificial" is the opposite of "natural". I argued there are
natural return values for these cases.
With such a return value, how does the caller distinguish between a
value that means that there were no elements, and the same value being
the actual minimum?

For an empty sequence, the returned value _is_ the _actual minimum_
(by the
proposed definition), in the very same way that 0 is the actual value
of an
empty sum and 1 is the actual value of an empty product.

No, they're not the same. The sum and the product of a sequence are
statements about the cumulative effect of an operation. The minimum
value in a set is a statement about a particular value, and if that
value isn't present in the set then there's something mighty fishy about
calling it the minimum value.
To put that a little more clearly: for a non-empty set, the sum and the
product of the elements is not necessarily a member of the set. The
minimum, on the other hand, is always a member of that set.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 7 '07 #37
Pete Becker wrote:
Kai-Uwe Bux wrote:
>>
However, "artificial" is the opposite of "natural". I argued there are
natural return values for these cases. If you consider them artificial,
then that still is a point of disagreement.

"Natural" means "existing in or caused by nature; not made or caused by
humankind." Isn't numeric_limits<int>::min() made by humankind?
Well, numeric_limits<int>::min() is made by man. However, that it is the
natural / right / non-artificial <g/ ... choice for

int max_value ( int* from, int* to );

to return is not really that dependent on man. Whenever you have a partially
ordered set (such as the possible values of type int), its maximum element,
should it have one, is the right / natural / canonical / most convenient
minimum value of the empty sequence of elements. It is the only choice that
makes certain formula hold in general (i.e., without the need of treating
the empty sequence separately). To some degree, it is of course a
convention (as is any definition). However, as often in mathematics, there
are better and worse conventions. It just proves very useful to define
empty sums, products, min, max, union, and intersection accordingly so that
theorems just come out right and can be stated in full generality. That's
why it feels so natural to do that.

As for programming, I would go with the same convention because I would
expect that there are cases where the right return value will eliminate the
need for extra code handling the empty sequence case separately. Whether
that holds in a particular application, depends of course on the specs. You
are right in that regard.
However, if I had to design a _library_ version of max_value(), I would go
with the math-inspired convention. I.e., I would prefer something like

template < typename T >
struct find_min {

T const & operator() ( T const & lhs, T const & rhs ) const {
return ( std::min( lhs, rhs ) );
}

};

template < typename IntIter >
typename std::iterator_traits< IntIter >::value_type
min_value_a ( IntIter from, IntIter to ) {
typedef typename std::iterator_traits< IntIter >::value_type value_type;
return
( std::accumulate( from, to,
std::numeric_limits< value_type >::max(),
find_min<value_type>() ) );
}

to

template < typename IntIter >
typename std::iterator_traits< IntIter >::value_type
min_value_b ( IntIter from, IntIter to ) {
return ( *min_element( from, to ) );
}

An additional reason is that I tend to avoid introducing undefined behavior
in library code unless there is a clear performance rational to do so.

I agree that the version a only applies to arithmetic types. Now, I would
consider that a GoodThing(tm) since in general there might be no maximum
value for a given type, in which case min_value() does indeed not allow for
a meaningful return value when confronted with an empty sequence. In those
cases, I would recommend min_element() anyway.

Or are we both using words a bit loosely, in order to convey meaning more
clearly?
That is very likely. At least, I plead guilty to that charge. I would
contend, there is nothing wrong with that as long as one is prepared to
work things out in the case of miscommunication.
Best

Kai-Uwe Bux
Mar 7 '07 #38
Pete Becker wrote:
Kai-Uwe Bux wrote:
>Pete Becker wrote:
>>Kai-Uwe Bux wrote:
However, "artificial" is the opposite of "natural". I argued there are
natural return values for these cases.
With such a return value, how does the caller distinguish between a
value that means that there were no elements, and the same value being
the actual minimum?

For an empty sequence, the returned value _is_ the _actual minimum_ (by
the proposed definition), in the very same way that 0 is the actual value
of an empty sum and 1 is the actual value of an empty product.

No, they're not the same. The sum and the product of a sequence are
statements about the cumulative effect of an operation. The minimum
value in a set is a statement about a particular value, and if that
value isn't present in the set then there's something mighty fishy about
calling it the minimum value.
>In general, the minimum of a sequence does not tell you anything about
its length. Why would you expect/want it to tell you that the sequence
was non-empty?

I don't want it to. Asking for the minimum value of an empty sequence is
meaningless, and returning a value that masquerades as an element of
that sequence doesn't make it meaningful. If you've got a set<intand
you look for its minimum value, you ought to be able to find that value
in the set. That's not the case for sum and product.
Ok, let me try again by recalling some Calculus. The infimum x of a set A of
numbers is the greatest lower bound for its elements characterized by

(a) x <= a for each a in A
(b) y <= x for each y satisfying (a) instead of x.

Sets may or may not have an infimum, and even if they have an infimum they
may not contain it as an element. Finite non-empty sets always have an
infimum and contain it as an element. The notion of infimum extends in a
natural way the notion of minimum, which after the fact can be defined as
an infimum that happens to be an element of the set.

The empty std::set<inthas an infimum, and this infimum is INT_MAX: to see
this, one just needs to let range x and y above range over all possible
values of type int. One finds that any value for x satisfies (a). Thus,
INT_MAX is the unique x satisfying (b). There is nothing meaningless about
it.

In view of your criticism, may I propose to change the name of the function
in order to avoid confusion:

int infimum ( int* from, int* to );

I have argued elsethread why I prefer this semantics for a library method to
undefined behavior. Note that I do not say this is better than
std::min_element().
As for whether this is the same as with + and *, I reiterate my previous
post: min(-,-) is a binary, associative operation. Whenever one is faced
with such an operation, the identity element with respect to this operation
is the formally correct choice for the iterated operation value of the
empty sequence, i.e., the unique value that makes concatenation of input
sequences commute with applying the iterated operation. In this formal
sense, it truly is the same convention as the one for empty sums and
products.

_If_ the caller wants to know whether an empty sequence was
>passed, the caller can check that by comparing the two iterators defining
the range (assuming that the signature reads something like:

template < typename IntIter >
int min_value ( IntIter from, IntIter to );

Or, even better, don't pretend that there's a value. Do what min_range
does, and return an iterator to the value, with end-of-sequence
designating that there was no minimum (i.e. the sequence was empty).
That is undeniably a viable option. At least it does not invoke undefined
behavior. However, I fail to see how it is _better_ and an absolute sense.
I see that it is more generic in that is applies to types that do not have
a maximum admissible value. However, that does not apply to built-in
arithmetic types for which a meaningful return value (greatest lower bound)
exists in all cases. The function does not pretend anything. It just has
well-defined and natural semantics for all inputs and that's all.
Best

Kai-Uwe Bux
Mar 7 '07 #39
Kai-Uwe Bux wrote:
>
That is undeniably a viable option. At least it does not invoke undefined
behavior. However, I fail to see how it is _better_ and an absolute sense.
Sheesh. Again: there is no better in an absolute sense. The best choice
of algorithm depends on what the desired result is, and there isn't
enough information in the original post, nor in any of the responses to
it, to choose a "best" algorithm for finding the minimum value of a set
of integers. Nevertheless, the response to the approach I initially
suggested has been to assert that other approaches are better. Nonsense.
End of discussion.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 7 '07 #40
Pete Becker wrote:
Kai-Uwe Bux wrote:
>>
That is undeniably a viable option. At least it does not invoke undefined
behavior. However, I fail to see how it is _better_ and an absolute
sense.

Sheesh. Again: there is no better in an absolute sense. The best choice of
algorithm depends on what the desired result is, and there isn't enough
information in the original post, nor in any of the responses to it, to
choose a "best" algorithm for finding the minimum value of a set of
integers.
You keep saying that when questioned about your claims, which come often
without proper qualification. I quote your previous post:
>_If_ the caller wants to know whether an empty sequence was
passed, the caller can check that by comparing the two iterators defining
the range (assuming that the signature reads something like:
template < typename IntIter >
int min_value ( IntIter from, IntIter to );

Or, even better, don't pretend that there's a value. Do what min_range
does, and return an iterator to the value, with end-of-sequence
designating that there was no minimum (i.e. the sequence was empty).
Note the use of the word "better" without any qualifications amounting to
the claim that returning an iterator is superior. Questioned about it, you
snip the claim in dispute and argue something entirely different.
Best

Kai-Uwe Bux
Mar 7 '07 #41
Kai-Uwe Bux wrote:
>
Note the use of the word "better" without any qualifications amounting to
the claim that returning an iterator is superior.
Indeed. Responding in kind.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Mar 7 '07 #42

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Bob Murdoch | last post: by
3 posts views Thread by papaja | last post: by
7 posts views Thread by mark.a.lemoine | last post: by
11 posts views Thread by Gregor Kovač | last post: by
8 posts views Thread by John | last post: by
1 post views Thread by CARIGAR | last post: by
reply views Thread by suresh191 | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.