Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #47934 > unrolled thread
| Started by | JiiPee <no@notvalid.com> |
|---|---|
| First post | 2017-01-11 18:17 +0000 |
| Last post | 2017-02-05 18:51 +0000 |
| Articles | 20 on this page of 78 — 16 participants |
Back to article view | Back to comp.lang.c++
Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-11 18:17 +0000
Re: Best way to handle mathematical divide-by-zero case "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> - 2017-01-11 20:00 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-11 19:16 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-12 10:36 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 13:16 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-12 15:23 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 16:13 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-12 17:35 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 16:27 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-12 17:37 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 16:44 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 16:46 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-13 12:06 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-13 11:36 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-13 13:12 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-13 13:11 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-13 15:23 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-13 14:57 +0000
Re: Best way to handle mathematical divide-by-zero case "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-01-13 17:35 -0800
Re: Best way to handle mathematical divide-by-zero case Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-13 20:25 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-14 18:08 +0100
Re: Best way to handle mathematical divide-by-zero case Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-14 20:30 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-15 00:16 +0100
Re: Best way to handle mathematical divide-by-zero case Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-01-15 00:34 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-15 01:01 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-15 16:57 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-15 17:17 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-15 19:13 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 16:48 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 16:51 +0000
Re: Best way to handle mathematical divide-by-zero case Manfred <mx2927@gmail.com> - 2017-02-06 01:08 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-02-06 00:39 +0000
Re: Best way to handle mathematical divide-by-zero case Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2017-02-06 00:50 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-02-06 02:01 +0100
Re: Best way to handle mathematical divide-by-zero case Manfred <noname@invalid.add> - 2017-02-06 13:56 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-02-06 22:25 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-02-06 22:26 +0000
Re: Best way to handle mathematical divide-by-zero case Robert Wessel <robertwessel2@yahoo.com> - 2017-02-06 16:46 -0600
Re: Best way to handle mathematical divide-by-zero case Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2017-02-06 23:49 +0000
Re: Best way to handle mathematical divide-by-zero case scott@slp53.sl.home (Scott Lurndal) - 2017-02-07 13:24 +0000
Re: Best way to handle mathematical divide-by-zero case Manfred <mx2927@gmail.com> - 2017-02-07 00:58 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-02-07 00:43 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-02-07 09:22 +0100
Re: Best way to handle mathematical divide-by-zero case Ben Bacarisse <ben.usenet@bsb.me.uk> - 2017-02-07 14:06 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-02-07 15:58 +0100
Re: Best way to handle mathematical divide-by-zero case Öö Tiib <ootiib@hot.ee> - 2017-02-07 01:00 -0800
Re: Best way to handle mathematical divide-by-zero case Manfred <noname@invalid.add> - 2017-02-07 15:31 +0100
Re: Best way to handle mathematical divide-by-zero case scott@slp53.sl.home (Scott Lurndal) - 2017-02-07 13:22 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 13:20 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-12 15:28 +0100
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 15:40 +0000
Re: Best way to handle mathematical divide-by-zero case David Brown <david.brown@hesbynett.no> - 2017-01-12 16:52 +0100
Re: Best way to handle mathematical divide-by-zero case Wouter van Ooijen <wouter@voti.nl> - 2017-01-11 23:20 +0100
Re: Best way to handle mathematical divide-by-zero case Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2017-01-11 21:43 +0000
Re: Best way to handle mathematical divide-by-zero case Gareth Owen <gwowen@gmail.com> - 2017-01-12 19:12 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 00:07 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 00:12 +0000
Re: Best way to handle mathematical divide-by-zero case Real Troll <real.troll@trolls.com> - 2017-01-12 12:55 -0400
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-12 16:53 +0000
Re: Best way to handle mathematical divide-by-zero case Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk> - 2017-01-12 19:10 +0000
Re: Best way to handle mathematical divide-by-zero case Gareth Owen <gwowen@gmail.com> - 2017-01-12 19:17 +0000
Re: Best way to handle mathematical divide-by-zero case "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-01-13 15:34 -0800
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-14 00:14 +0000
Re: Best way to handle mathematical divide-by-zero case "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-01-13 16:56 -0800
Re: Best way to handle mathematical divide-by-zero case "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-01-13 17:46 -0800
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-14 01:51 +0000
Re: Best way to handle mathematical divide-by-zero case "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-01-13 18:09 -0800
Re: Best way to handle mathematical divide-by-zero case Gareth Owen <gwowen@gmail.com> - 2017-01-14 11:21 +0000
Re: Best way to handle mathematical divide-by-zero case "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-01-14 12:45 -0800
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-01-14 21:02 +0000
Re: Best way to handle mathematical divide-by-zero case "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-01-14 13:47 -0800
Re: Best way to handle mathematical divide-by-zero case "Chris M. Thomasson" <invalid@invalid.invalid> - 2017-01-14 13:03 -0800
Re: Best way to handle mathematical divide-by-zero case "J. Clarke" <j.clarke.873638@gmail.com> - 2017-02-04 07:56 -0500
Re: Best way to handle mathematical divide-by-zero case Jorgen Grahn <grahn+nntp@snipabacken.se> - 2017-02-05 10:21 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-02-05 13:33 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-02-06 07:33 +0000
Re: Best way to handle mathematical divide-by-zero case JiiPee <no@notvalid.com> - 2017-02-05 13:34 +0000
Re: Best way to handle mathematical divide-by-zero case Jorgen Grahn <grahn+nntp@snipabacken.se> - 2017-02-05 18:51 +0000
Page 1 of 4 [1] 2 3 4 Next page →
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-11 18:17 +0000 |
| Subject | Best way to handle mathematical divide-by-zero case |
| Message-ID | <zEudA.1117322$_a3.924316@fx42.am4> |
In my interview the interviewer asked me to write a function to
calculate an average value/mean.
And at the end he added: "..and if you divide by zero then you would
maybe throw an exception....". But I have since been thinking is this
the way:
double average(array of values)
{}
Seems like Bjarne recommends not to use exceptions when dividing by zero
but other ways. What would be the best way for the function to report
about "dividing by zero" case? How would you do it?
I kind of agree with Bjarne here.... do you?
[toc] | [next] | [standalone]
| From | "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2017-01-11 20:00 +0100 |
| Message-ID | <o55va9$s59$1@dont-email.me> |
| In reply to | #47934 |
On 11.01.2017 19:17, JiiPee wrote:
> In my interview the interviewer asked me to write a function to
> calculate an average value/mean.
>
> And at the end he added: "..and if you divide by zero then you would
> maybe throw an exception....". But I have since been thinking is this
> the way:
>
> double average(array of values)
>
> {}
>
> Seems like Bjarne recommends not to use exceptions when dividing by zero
> but other ways. What would be the best way for the function to report
> about "dividing by zero" case? How would you do it?
>
>
> I kind of agree with Bjarne here.... do you?
I think your question is really three different questions:
• How to report division by zero for floating point calculations.
Easy, that's what NaN is all about.
• How to report division by zero for integer calculations.
Crash.
• How to sensibly deal with an empty set of values for `average`.
More thorny, discussed below.
Consider a multiset S of N numbers. Its average is avg(S) = sum(S)/N.
Now we form the set T = S ⊎ {42}, with N+1 numbers. Its average is
avg(T) = sum(T)/(N+1) = (42 + N*avg(S))/(N+1). A nice update formula.
So what if we want that to work for the case N = 0, i.e. S = {}?
Well, then N*avg(S), i.e. N*avg({}), should better equal 0. And it is 0
no matter which number we choose for avg({}). Unfortunately 0*NaN yields
NaN, but the choice that avg({}) = 0 sounds OK to me.
Another possibility is to return NaN, or to return an empty `Optional`
like `boost::optional` or C++17 `std::optional`. Or one could throw an
exception. Or, one could document the function's contract as requiring a
non-empty set, and then crash/assert on contract violation.
I think the most practically useful behavior would be the 0 return,
documented as such.
But, this opinion could be subject to revision if someone makes a good
case for some other possibility! ;-)
Cheers!,
- Af
[toc] | [prev] | [next] | [standalone]
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-11 19:16 +0000 |
| Message-ID | <cwvdA.547229$AS2.194354@fx32.am4> |
| In reply to | #47935 |
On 11/01/2017 19:00, Alf P. Steinbach wrote: > I think the most practically useful behavior would be the 0 return, > documented as such. But average can also be 0, cant it? So we cannot return 0 (zero) ...
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-12 10:36 +0100 |
| Message-ID | <o57ijl$e39$1@dont-email.me> |
| In reply to | #47936 |
On 11/01/17 20:16, JiiPee wrote: > On 11/01/2017 19:00, Alf P. Steinbach wrote: >> I think the most practically useful behavior would be the 0 return, >> documented as such. > > But average can also be 0, cant it? So we cannot return 0 (zero) ... Of course you can return 0 if you want. The average of any empty set is not defined - it simply does not make sense to take the sum of the values and divide by the number of values when the set is empty. So if you are writing a function to calculate an average, you have three options. First, you can leave it undefined - it's okay to have "garbage in, garbage out". Just ignore the possibility. This is a perfectly reasonable attitude, and it is the most efficient one for both developer time and run time. But it requires that the function be used correctly, or behaviour is undefined and may launch nasal daemons, corrupt your files, or anything else. Secondly, you can specify the behaviour of the function with empty sets. Then it is up to you, as the writer of the specification, to say what you will do when given an empty set. Possibilities include returning 0, returning NaN, throwing an exception, calling an error handler, popping up a message, killing the program with an error message. You can even return 42 if you like - as long as you say what the function will do in this case, and do it. Usually it is best to do something obvious and sensible, of course - returning 0 is fine, but returning 42 would look a bit odd. Thirdly, you can leave it as unspecified behaviour. Here you say that the function will return a value of the declared type (double, int, whatever), without crashing or causing other problems. You just don't say what number that will be. Typically the implementation will pick a value (such as 0 or NaN), but you don't specify that value for the function. This third option is often the best for general use. If someone uses the function incorrectly (passing an empty set), they have a bug in their code - but your function implementation is not going to make the situation worse. The second option may be nicer as an aid to debugging - it can make it easier for the person who wrote the code to find possible errors. The first option is fine when there is tight cooperation between the author of the function, and its user.
[toc] | [prev] | [next] | [standalone]
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-12 13:16 +0000 |
| Message-ID | <dlLdA.831942$7m2.231803@fx37.am4> |
| In reply to | #47949 |
On 12/01/2017 09:36, David Brown wrote: > On 11/01/17 20:16, JiiPee wrote: >> On 11/01/2017 19:00, Alf P. Steinbach wrote: >>> I think the most practically useful behavior would be the 0 return, >>> documented as such. >> But average can also be 0, cant it? So we cannot return 0 (zero) ... > Of course you can return 0 if you want. If we have a set of numbers: -1, 0 , 1 we have 3 numbers and their average value/mean is 0. And there was no errors or dividing by zero... :)
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-12 15:23 +0100 |
| Message-ID | <o583e1$pjv$1@dont-email.me> |
| In reply to | #47951 |
On 12/01/17 14:16, JiiPee wrote:
> On 12/01/2017 09:36, David Brown wrote:
>> On 11/01/17 20:16, JiiPee wrote:
>>> On 11/01/2017 19:00, Alf P. Steinbach wrote:
>>>> I think the most practically useful behavior would be the 0 return,
>>>> documented as such.
>>> But average can also be 0, cant it? So we cannot return 0 (zero) ...
>> Of course you can return 0 if you want.
>
>
> If we have a set of numbers: -1, 0 , 1 we have 3 numbers and their
> average value/mean is 0. And there was no errors or dividing by zero... :)
>
I am perfectly aware that the average of a non-empty set of numbers can
be 0. That does not conflict with 0 being a sensible return value when
the function is called with an empty set. It means that the caller
cannot write:
int x = average(set);
if (x == 0) {
printf("The set was empty\n");
} else {
printf("The average is %i\n, x);
}
But unless the user of the function particularly incompetent, or you
have specifically said the function will handle empty sets in a way that
is suitable here, then the user will never do this. Instead, they will
write:
if (isempty(set)) {
printf("The set was empty\n");
} else {
int x = average(set);
printf("The average is %i\n, x);
}
The reason you make the function return 0 on an empty set is so that
when a user writes this :
int x = average(set);
printf("The average is %i\n, x);
and "set" happens to be empty, then they will get the output "The
average is 0\n", rather than "Launching nasal daemons...\n".
[toc] | [prev] | [next] | [standalone]
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-12 16:13 +0000 |
| Message-ID | <GWNdA.1079197$kM7.734263@fx44.am4> |
| In reply to | #47954 |
On 12/01/2017 14:23, David Brown wrote:
> The reason you make the function return 0 on an empty set is so that
> when a user writes this :
>
> int x = average(set);
> printf("The average is %i\n, x);
>
> and "set" happens to be empty, then they will get the output "The
> average is 0\n", rather than "Launching nasal daemons...\n".
I see, so you just want to prevent a crash if all debugging and testing
fails to find that error.
Because an assert() would do the job, but I guess you think debugging
cannot find the errror situation?
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-12 17:35 +0100 |
| Message-ID | <o58b5q$nen$1@dont-email.me> |
| In reply to | #47958 |
On 12/01/17 17:13, JiiPee wrote:
> On 12/01/2017 14:23, David Brown wrote:
>> The reason you make the function return 0 on an empty set is so that
>> when a user writes this :
>>
>> int x = average(set);
>> printf("The average is %i\n, x);
>>
>> and "set" happens to be empty, then they will get the output "The
>> average is 0\n", rather than "Launching nasal daemons...\n".
>
>
> I see, so you just want to prevent a crash if all debugging and testing
> fails to find that error.
>
> Because an assert() would do the job, but I guess you think debugging
> cannot find the errror situation?
>
It won't necessarily prevent a crash. It will simply provide a
consistent, efficient, and not unreasonable value in the case of an
unreasonable call. In some cases, it might even be considered a useful
part of the specification of the function that the user could rely on
(so that the user does not need to check for empty sets before calling
average).
[toc] | [prev] | [next] | [standalone]
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-12 16:27 +0000 |
| Message-ID | <78OdA.1094575$zq4.804012@fx41.am4> |
| In reply to | #47954 |
On 12/01/2017 14:23, David Brown wrote:
> The reason you make the function return 0 on an empty set is so that
> when a user writes this :
>
> int x = average(set);
> printf("The average is %i\n, x);
>
> and "set" happens to be empty, then they will get the output "The
> average is 0\n", rather than "Launching nasal daemons...\n".
I see. But in this case I would prefer to use NaN or max_double so the
user would see there is something wrong going on. Because 0 return looks
like a success, but getting max_double would surely be noticed.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-12 17:37 +0100 |
| Message-ID | <o58ba3$nen$2@dont-email.me> |
| In reply to | #47959 |
On 12/01/17 17:27, JiiPee wrote:
> On 12/01/2017 14:23, David Brown wrote:
>> The reason you make the function return 0 on an empty set is so that
>> when a user writes this :
>>
>> int x = average(set);
>> printf("The average is %i\n, x);
>>
>> and "set" happens to be empty, then they will get the output "The
>> average is 0\n", rather than "Launching nasal daemons...\n".
>
>
> I see. But in this case I would prefer to use NaN or max_double so the
> user would see there is something wrong going on.
Feel free - it is your choice.
Personally, I don't like NaNs, and I don't have any use for max_double
because I don't like comparing floating point types for equality (even
though it would work in this case). And I don't like the idea that a
function might fail and return a weird value - to mind mind, functions
never fail, only specifications.
> Because 0 return looks
> like a success, but getting max_double would surely be noticed.
>
[toc] | [prev] | [next] | [standalone]
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-12 16:44 +0000 |
| Message-ID | <HnOdA.1081509$kM7.63763@fx44.am4> |
| In reply to | #47961 |
On 12/01/2017 16:37, David Brown wrote: > And I don't like the idea that a > function might fail and return a weird value - to mind mind, functions > never fail, only specifications. But the way you use that function, the following situation could happen: The user read values from a file and gets a zero set and calculates the average using. The coder forgot to check the zero set (a bug in the code) so the program prints: > Average is 0. But if you return max_double it would print like: > Avarage is 99999999999999. which one makes it easier to find that there was a hidden error? :) The second one, right? So the user of the program can now report this error and fix. But if the use gets 0, then they think all is fine and they might try to find the error from other place later on.
[toc] | [prev] | [next] | [standalone]
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-12 16:46 +0000 |
| Message-ID | <lpOdA.1081536$kM7.30551@fx44.am4> |
| In reply to | #47962 |
On 12/01/2017 16:44, JiiPee wrote: > > > > Avarage is 99999999999999. > > which one makes it easier to find that there was a hidden error? :) > > The second one, right? So the user of the program can now report this > error and fix. But if the use gets 0, then they think all is fine and > they might try to find the error from other place later on. So I a little bit agree with C-programmers argument here that "its good that the program crashes... at least we can find the error then", rather than a hidden error and then difficult to find where it is. At least here we know where the error is.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-13 12:06 +0100 |
| Message-ID | <o5ac85$puv$1@dont-email.me> |
| In reply to | #47962 |
On 12/01/17 17:44, JiiPee wrote: > On 12/01/2017 16:37, David Brown wrote: >> And I don't like the idea that a >> function might fail and return a weird value - to mind mind, functions >> never fail, only specifications. > > > But the way you use that function, the following situation could happen: > > The user read values from a file and gets a zero set and calculates the > average using. The coder forgot to check the zero set (a bug in the > code) so the program prints: > >> Average is 0. > > But if you return max_double it would print like: > >> Avarage is 99999999999999. > > which one makes it easier to find that there was a hidden error? :) > > The second one, right? So the user of the program can now report this > error and fix. But if the use gets 0, then they think all is fine and > they might try to find the error from other place later on. > In some situations, that might make it easier to spot the problem. In other situations, it is far worse. Suppose this is code in your internet-enabled fridge, which is measuring the average amount of coke you drink so that it can pre-order enough for your expected needs next month. If you don't drink coke, and it is averaging an empty set, would you rather your fridge ordered 0 cokes for next month, of 99999999999999 bottles? If you are writing a general function without knowing /all/ of its usage, then you do not have any basis for saying that returning "max_double" is somehow "better" than returning 0. If the user puts in incorrect data, then your result will /always/ be wrong - no matter what you return. It is /always/ the function user's responsibility to pass correct data to a function.
[toc] | [prev] | [next] | [standalone]
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-13 11:36 +0000 |
| Message-ID | <PY2eA.1220544$IJ6.1111381@fx46.am4> |
| In reply to | #48010 |
On 13/01/2017 11:06, David Brown wrote:
> In some situations, that might make it easier to spot the problem. In
> other situations, it is far worse. Suppose this is code in your
> internet-enabled fridge, which is measuring the average amount of coke
> you drink so that it can pre-order enough for your expected needs next
> month. If you don't drink coke, and it is averaging an empty set, would
> you rather your fridge ordered 0 cokes for next month, of 99999999999999
> bottles?
But I would not code it like that. I would do like this:
avCoke = average(..);
if(avCoke > 9999)
something_is_wrong_so_report_about_this();
else
orderCokes();
so i would check that value *before action*. The problem with 0 is that
even if we are checking it it does not raise any concerns as it is a
valid value (zero cokes looks just fine ... but would be wrong here).
This was my whole idea, that we check the value *before doing action*.
So odd values can be identified.
>
> If you are writing a general function without knowing/all/ of its
> usage, then you do not have any basis for saying that returning
> "max_double" is somehow "better" than returning 0.
It might be better in a way that it causes "more mess" so its more
detectable. 0 does not normally cause any doubts (unless a pointer
value). Thats why I chose max-values if I have to chose an error value.
Many C-programmers say the same: "its good that the program crashes so
we can find the error and fix it". In a way it makes sense sometimes.
Its better that the program crashes rather than that it causes damage is
not noticed.
But it also depends on where its used. Obviously if its about cars speed
we might prefer to return 0 rather than make the car go max speed. But
when debugging its easier to find the bug if I get a value 999999999999.
> If the user puts in
> incorrect data, then your result will/always/ be wrong - no matter what
> you return.
but the difference is that with 0 we dont find out that the result was
wrong but with 9999999999 we will more easily see that the result is wrong.
> It is/always/ the function user's responsibility to pass
> correct data to a function.
We are talking here if that fails... so security after that.
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-13 13:12 +0100 |
| Message-ID | <o5ag4v$7n1$1@dont-email.me> |
| In reply to | #48011 |
On 13/01/17 12:36, JiiPee wrote: > On 13/01/2017 11:06, David Brown wrote: >> In some situations, that might make it easier to spot the problem. In >> other situations, it is far worse. Suppose this is code in your >> internet-enabled fridge, which is measuring the average amount of coke >> you drink so that it can pre-order enough for your expected needs next >> month. If you don't drink coke, and it is averaging an empty set, would >> you rather your fridge ordered 0 cokes for next month, of 99999999999999 >> bottles? > > But I would not code it like that. I would do like this: > avCoke = average(..); > if(avCoke > 9999) > something_is_wrong_so_report_about_this(); > else > orderCokes(); > > so i would check that value *before action*. The problem with 0 is that > even if we are checking it it does not raise any concerns as it is a > valid value (zero cokes looks just fine ... but would be wrong here). > > This was my whole idea, that we check the value *before doing action*. > So odd values can be identified. If you check the value /before/ doing action, then you would check the size of the set before finding the average, and thus write /correct/ code. What you are asking is for a way to call a function with "garbage in, garbage out", and somehow distinguish the resulting "garbage out". And I would far rather that my fridge ordered 99999999999999 bottles of coke - because the shop would refuse the order and tell me my fridge is broken. If it ordered 9999 bottles, the shop might just think I was planning a huge party. Your example here simply demonstrates that there is /no/ good choice of a value that you can return that indicates a failure. If you want to indicate a failure, you need to do it with a /specific/ and /explicit/ mechanism - such as an exception, or returning a <success, value> pair. If you are willing to accept that the function user's mistake is the function user's problem, then returning 0 is just as good as any other value, because /all/ other values could cause problems for badly written code, just as 0 could. > >> It is/always/ the function user's responsibility to pass >> correct data to a function. > > We are talking here if that fails... so security after that. > You /cannot/ fix the broken function user's code from within /your/ function. You can somewhat reduce the risk of further damage, and you can sometimes make it easier to debug the problem, but that is all. There are times when the /best/ thing to do when detecting bad input is to crash the program with an error message - and times when that is the /worst/ think to do. Please understand this, and stop trying to come up with different return values and different circumstances. There is /no/ correct answer here. If people pass invalid input to a function, you cannot give a sensible result. You may /specify/ a given result for a given input, in which case that input is no longer valid - but it is again up to the function's user to understand what the function does. This has been understood since the beginning of programmable computers some 200 years ago, and is just as true today: <https://www.brainyquote.com/quotes/authors/c/charles_babbage.html> > On two occasions I have been asked, 'Pray, Mr. Babbage, if you put > into the machine wrong figures, will the right answers come out?' I > am not able rightly to apprehend the kind of confusion of ideas that > could provoke such a question.
[toc] | [prev] | [next] | [standalone]
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-13 13:11 +0000 |
| Message-ID | <3m4eA.1026185$4Z7.226950@fx38.am4> |
| In reply to | #48014 |
On 13/01/2017 12:12, David Brown wrote: > On 13/01/17 12:36, JiiPee wrote: >> On 13/01/2017 11:06, David Brown wrote: >>> In some situations, that might make it easier to spot the problem. In >>> other situations, it is far worse. Suppose this is code in your >>> internet-enabled fridge, which is measuring the average amount of coke >>> you drink so that it can pre-order enough for your expected needs next >>> month. If you don't drink coke, and it is averaging an empty set, would >>> you rather your fridge ordered 0 cokes for next month, of 99999999999999 >>> bottles? >> But I would not code it like that. I would do like this: >> avCoke = average(..); >> if(avCoke > 9999) >> something_is_wrong_so_report_about_this(); >> else >> orderCokes(); >> >> so i would check that value *before action*. The problem with 0 is that >> even if we are checking it it does not raise any concerns as it is a >> valid value (zero cokes looks just fine ... but would be wrong here). >> >> This was my whole idea, that we check the value *before doing action*. >> So odd values can be identified. > If you check the value /before/ doing action, then you would check the > size of the set before finding the average, and thus write /correct/ code. it depends... Lets think about situation where the user observes values printed on the screen and acts upon it. In that case we do not have any checks in the code, but the user checks the values by looking at the screen. IN this situation average value: 99999999999 printed on the screen surely would be better than 0, isnt it? > > What you are asking is for a way to call a function with "garbage in, > garbage out", and somehow distinguish the resulting "garbage out". yes. If the console prints: "999999999999" its easy for the user to spot it. > And I would far rather that my fridge ordered 99999999999999 bottles of > coke - because the shop would refuse the order and tell me my fridge is > broken. If it ordered 9999 bottles, the shop might just think I was > planning a huge party. well that was only an example... we can have: if (> 9999999999) And no code should be made to order automatically any number of cokes... of course the program would need to check how many cokes are ordered. OR course there are many checks that there is a limit how much can be ordered. No sane program would allow to order 999999999 cokes. > Your example here simply demonstrates that there is /no/ good choice of > a value that you can return that indicates a failure. but if the user sees the value on a screen, 999999999 is easier to spot than 0, isnt it? > If you want to > indicate a failure, you need to do it with a /specific/ and /explicit/ > mechanism - such as an exception, or returning a <success, value> pair. > If you are willing to accept that the function user's mistake is the > function user's problem, then returning 0 is just as good as any other > value, because /all/ other values could cause problems for badly written > code, just as 0 could. but in many cases 9999999999999999 is easier to spot than 0, isnt it? like if the values are printed on the screen (which they are in many programs). > >>> It is/always/ the function user's responsibility to pass >>> correct data to a function. >> We are talking here if that fails... so security after that. >> > You /cannot/ fix the broken function user's code from within /your/ > function. You can somewhat reduce the risk of further damage, and you > can sometimes make it easier to debug the problem, but that is all. > There are times when the /best/ thing to do when detecting bad input is > to crash the program with an error message - and times when that is the > /worst/ think to do. > > Please understand this, and stop trying to come up with different return > values and different circumstances. There is /no/ correct answer here. > If people pass invalid input to a function, you cannot give a sensible > result. but even with pointers.... if we cannot put any sensible value, we normally want to put NULL, because its easier to find that error rather than put an address which points to an object which does not exist. When debugging, NULL value is easier to spot than some valid/invalid object address value. I dont know, I dont feel like returning 0 in average() if there was an error, beacause that might confuse to think everything is fine....
[toc] | [prev] | [next] | [standalone]
| From | David Brown <david.brown@hesbynett.no> |
|---|---|
| Date | 2017-01-13 15:23 +0100 |
| Message-ID | <o5anq5$b6d$1@dont-email.me> |
| In reply to | #48015 |
On 13/01/17 14:11, JiiPee wrote: > but even with pointers.... if we cannot put any sensible value, we > normally want to put NULL, because its easier to find that error rather > than put an address which points to an object which does not exist. When > debugging, NULL value is easier to spot than some valid/invalid object > address value. Pointers are a little different because they have a specific value that indicates "does not point to a valid object", i.e., NULL. (Non-null pointers may also fail to point to valid objects, of course.) It is also common practice to check for NULL pointers in code - though of course people may fail to do so. NaN's are a possible signal type for functions returning a double, but how often do people check for them? Anyone that is a careful enough programmer to check that the result of your average function is not an NaN or infinity, is going to be careful enough to check that they don't pass invalid data (an empty set) to your function in the first place. The only real use of NaNs here is if the average function specifically says it will return NaN on bad input, the high level code is written by someone who expects intermediary functions to return NaN on errors, and the middle layer (that calls the average function) is written by a muppet and never checked by someone who can actually write correct code. > > I dont know, I dont feel like returning 0 in average() if there was an > error, beacause that might confuse to think everything is fine.... Any value you return for a function which received invalid data /will/ be wrong. It does not matter what value you pick - there will be circumstances in which that value is wrong, and for which that value is difficult to spot in debugging or testing. It is certainly possible to pick a return value that is easier for debugging in /some/ cases - but that value can never be the "best" choice in all cases. You need to understand that, and accept that - or else you will spend a great deal of effort trying to do the impossible.
[toc] | [prev] | [next] | [standalone]
| From | JiiPee <no@notvalid.com> |
|---|---|
| Date | 2017-01-13 14:57 +0000 |
| Message-ID | <YV5eA.1229202$IJ6.783410@fx46.am4> |
| In reply to | #48019 |
On 13/01/2017 14:23, David Brown wrote: > pick a return value that is easier for debugging in/some/ cases - but > that value can never be the "best" choice in all cases. sure, if its about "how many time we shoot with a weapon", then 0 is pretty safe return value rather than 999999999.
[toc] | [prev] | [next] | [standalone]
| From | "Chris M. Thomasson" <invalid@invalid.invalid> |
|---|---|
| Date | 2017-01-13 17:35 -0800 |
| Message-ID | <o5bv5v$4gd$1@dont-email.me> |
| In reply to | #48019 |
On 1/13/2017 6:23 AM, David Brown wrote: > On 13/01/17 14:11, JiiPee wrote: > >> but even with pointers.... if we cannot put any sensible value, we >> normally want to put NULL, because its easier to find that error rather >> than put an address which points to an object which does not exist. When >> debugging, NULL value is easier to spot than some valid/invalid object >> address value. [...] > Any value you return for a function which received invalid data /will/ > be wrong. [...] What about the "deadlier" case of "kind of" totally wrong? IMVHO, best to try and "spot/detect" these things before said nasal demons splatter on proverbial Murphy's law shi% storm rising. A plot with nans tends to be "easy" to "visually" spot for the rendering tends to resemble the background color: Damn it! ;^o
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2017-01-13 20:25 +0000 |
| Message-ID | <87bmvapv13.fsf@bsb.me.uk> |
| In reply to | #48010 |
On the average of no values... David Brown <david.brown@hesbynett.no> writes: > On 12/01/17 17:44, JiiPee wrote: <snip> >> But the way you use that function, the following situation could happen: >> >> The user read values from a file and gets a zero set and calculates the >> average using. The coder forgot to check the zero set (a bug in the >> code) so the program prints: >> >>> Average is 0. >> >> But if you return max_double it would print like: >> >>> Avarage is 99999999999999. >> >> which one makes it easier to find that there was a hidden error? :) >> >> The second one, right? So the user of the program can now report this >> error and fix. But if the use gets 0, then they think all is fine and >> they might try to find the error from other place later on. > > In some situations, that might make it easier to spot the problem. In > other situations, it is far worse. Suppose this is code in your > internet-enabled fridge, which is measuring the average amount of coke > you drink so that it can pre-order enough for your expected needs next > month. If you don't drink coke, and it is averaging an empty set, would > you rather your fridge ordered 0 cokes for next month, of 99999999999999 > bottles? The average here would over time (the result being bottles/week or ml/day or whatever). The zero quantity is on the top of the division. <snip> -- Ben.
[toc] | [prev] | [next] | [standalone]
Page 1 of 4 [1] 2 3 4 Next page →
Back to top | Article view | comp.lang.c++
csiph-web