Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #47934 > unrolled thread

Best way to handle mathematical divide-by-zero case

Started byJiiPee <no@notvalid.com>
First post2017-01-11 18:17 +0000
Last post2017-02-05 18:51 +0000
Articles 20 on this page of 78 — 16 participants

Back to article view | Back to comp.lang.c++


Contents

  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 →


#47934 — Best way to handle mathematical divide-by-zero case

FromJiiPee <no@notvalid.com>
Date2017-01-11 18:17 +0000
SubjectBest 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]


#47935

From"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>
Date2017-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]


#47936

FromJiiPee <no@notvalid.com>
Date2017-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]


#47949

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#47951

FromJiiPee <no@notvalid.com>
Date2017-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]


#47954

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#47958

FromJiiPee <no@notvalid.com>
Date2017-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]


#47960

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#47959

FromJiiPee <no@notvalid.com>
Date2017-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]


#47961

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#47962

FromJiiPee <no@notvalid.com>
Date2017-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]


#47963

FromJiiPee <no@notvalid.com>
Date2017-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]


#48010

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#48011

FromJiiPee <no@notvalid.com>
Date2017-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]


#48014

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#48015

FromJiiPee <no@notvalid.com>
Date2017-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]


#48019

FromDavid Brown <david.brown@hesbynett.no>
Date2017-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]


#48020

FromJiiPee <no@notvalid.com>
Date2017-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]


#48028

From"Chris M. Thomasson" <invalid@invalid.invalid>
Date2017-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]


#48021

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2017-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