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


Groups > comp.lang.c > #174243 > unrolled thread

Re: bart again (UCX64)

Started bycandycane@f172.n1.z21.fsxnet (candycane)
First post2023-09-06 19:53 +1300
Last post2023-09-09 10:23 -0700
Articles 20 on this page of 129 — 12 participants

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


Contents

  Re: bart again (UCX64) candycane@f172.n1.z21.fsxnet (candycane) - 2023-09-06 19:53 +1300
    Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-07 12:00 -0700
      Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 16:33 -0700
        Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-07 20:55 -0700
          Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-07 22:16 -0700
            Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-08 07:09 +0000
              Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 10:10 +0200
                Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-08 01:30 -0700
                  Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 11:26 +0200
                    Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-08 10:44 +0100
                      Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 13:26 +0200
                        Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 01:57 +0000
                          Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-09 18:36 +0200
                            Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 18:19 +0000
                              Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-10 13:28 +0200
                                Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-10 13:20 +0100
                                  Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-10 15:19 +0200
                                    Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-10 16:07 +0100
                                      Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-10 18:33 +0200
                                Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-10 15:44 +0000
                                  Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-10 18:36 +0200
                      Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 01:48 +0000
                        Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-09 19:04 +0200
                    Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-08 02:47 -0700
                      Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 16:03 +0200
                        Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-08 16:06 -0700
                          Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-09 01:52 +0100
                            Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-08 18:16 -0700
                              Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-09 21:31 +0100
                          Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-10 12:03 +0200
                            Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-10 21:36 -0700
                              Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-11 08:51 +0200
                                Re: bart again (UCX64) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-10 23:59 -0700
                                Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-11 01:01 -0700
                                  Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-11 11:17 +0200
                                    Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-11 03:16 -0700
                                      Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-11 14:58 +0200
                                        Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-11 06:35 -0700
                                          Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-11 14:13 +0000
                                          Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-11 16:24 +0200
                                        Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-11 14:55 +0100
                                          Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-11 16:42 +0200
                                        Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-11 14:29 +0000
                                Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-11 11:25 +0100
                                  Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-11 03:59 -0700
                                    Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-11 13:57 +0000
                                      Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-11 09:52 -0700
                                  Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-11 16:07 +0200
                                  Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-11 16:26 +0100
                                    Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-11 16:47 +0100
                                      Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-11 19:14 +0200
                                      Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-11 22:30 +0100
                                        Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-11 23:07 +0100
                                          Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-11 23:31 +0000
                                            Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-12 09:18 +0200
                                          Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-12 03:01 +0100
                                    Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-11 10:08 -0700
                                      Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-11 23:18 +0100
                                        Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-11 23:37 +0100
                                          Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-11 15:46 -0700
                                            Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-11 23:40 +0000
                                              Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-12 01:50 +0100
                                                Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-11 17:59 -0700
                                                Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-12 01:03 +0000
                                                Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-12 02:39 +0100
                                                  Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-12 11:28 +0100
                                                    Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-12 14:49 +0100
                                                      Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-12 15:18 +0100
                                          Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-12 03:58 +0100
                                            Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-12 02:25 -0700
                                              Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-12 16:17 +0100
                                                Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-12 17:28 +0100
                                                  Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-12 21:07 +0200
                                                    Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-13 03:01 +0100
                                                      Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-13 09:38 +0200
                                                        Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-13 10:00 +0200
                                                      Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-19 05:22 -0700
                                                        Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-19 14:29 +0100
                                                  Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-13 13:35 +0100
                                                    Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-13 20:48 +0100
                                                    Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-19 05:53 -0700
                                                Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-12 09:33 -0700
                                                  Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-12 16:48 +0000
                                                    Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-12 10:57 -0700
                                                      Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-12 18:07 +0000
                                                        Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-12 21:23 +0200
                                                          Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-13 02:07 -0700
                                                            Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-13 12:43 +0200
                                                              Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-13 04:04 -0700
                                                                Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-13 14:07 +0200
                                                        Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-13 01:47 -0700
                                                          Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-13 13:02 +0200
                                                            Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-13 04:45 -0700
                                                              Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-13 14:36 +0200
                                                                Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-13 13:43 +0000
                                                                  Re: bart again (UCX64) James Kuyper <jameskuyper@alumni.caltech.edu> - 2023-09-13 11:10 -0400
                                                                    Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-13 17:12 +0000
                                                                      [meta] spam in thread Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-13 11:22 -0700
                                                                        Re: [meta] spam in thread Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-13 18:40 +0000
                                                                          Re: [meta] spam in thread Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-13 11:48 -0700
                                                                        Re: [meta] spam in thread David Brown <david.brown@hesbynett.no> - 2023-09-13 21:01 +0200
                                                                      Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-13 19:58 +0100
                                                                  Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-18 12:36 -0700
                                                                    Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-18 13:40 -0700
                                                                      Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-09-20 19:43 -0700
                                                                        Re: bart again (UCX64) "Chris M. Thomasson" <chris.m.thomasson.1@gmail.com> - 2023-09-20 20:14 -0700
                                                                        Re: bart again (UCX64) Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2023-09-20 22:10 -0700
                                                                          Re: bart again (UCX64) Tim Rentsch <tr.17687@z991.linuxsc.com> - 2023-10-01 11:03 -0700
                                                                Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-13 07:39 -0700
                                                                  Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-13 15:18 +0000
                                                                  Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-13 18:39 +0200
                                                  Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-13 15:44 +0100
                                                    Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-13 08:42 -0700
                                                      Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-13 22:35 +0100
                                                    Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-13 18:49 +0200
                                        Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-11 15:40 -0700
                                          Re: bart again (UCX64) Ben Bacarisse <ben.usenet@bsb.me.uk> - 2023-09-12 03:36 +0100
                                          Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-12 12:58 +0200
                                      Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-12 12:49 +0200
                                        Re: bart again (UCX64) Bart <bc@freeuk.com> - 2023-09-12 12:52 +0100
                                          Re: bart again (UCX64) Malcolm McLean <malcolm.arthur.mclean@gmail.com> - 2023-09-12 05:22 -0700
                                          Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-12 15:05 +0200
                    Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 02:17 +0000
                      Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-10 14:44 +0200
                  Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-08 14:36 +0000
                    Re: bart again (UCX64) Kaz Kylheku <864-117-4973@kylheku.com> - 2023-09-09 01:50 +0000
                      Re: bart again (UCX64) scott@slp53.sl.home (Scott Lurndal) - 2023-09-09 15:40 +0000
            Re: bart again (UCX64) David Brown <david.brown@hesbynett.no> - 2023-09-08 09:57 +0200
            Re: bart again (UCX64) Richard Damon <Richard@Damon-Family.org> - 2023-09-09 10:23 -0700

Page 5 of 7 — ← Prev page 1 2 3 4 [5] 6 7  Next page →


#176024

FromTim Rentsch <tr.17687@z991.linuxsc.com>
Date2023-09-19 05:53 -0700
Message-ID<86sf7al3xh.fsf@linuxsc.com>
In reply to#175385
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:

> Bart <bc@freeuk.com> writes:
>
>> On 12/09/2023 16:17, Ben Bacarisse wrote:
>>
>>> Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
>>>
>>>> No we can't use Haskell.
>>>
>>> That's a shame.  The Glasgow Haskell compiler reports that in
>>>    sign ::  Double -> Int
>>>    sign x | x <  0 = -1
>>>           | x == 0 =  0
>>>           | x >  0 =  1
>>> the guards are non-exhaustive.
>>
>> You can do a much simpler check in any language that doesn't need
>> clever analysis or knowledge of the special properties of NaNs.
>>
>> Because the last return/last value is conditional, it can fail, but
>> there is no value associated with that failing path.
>
> But that is not always true.  Multiple conditions can be exhaustive.
> For example, Malcolm's sign:
>
>   double sign(double x)
>   {
>         if ( x <  0 ) return -1;
>         if ( x == 0 ) return  0;
>         if ( x >  0 ) return  1;
>         if (isnan(x)) return  x;
>   }
>
>> That can [be] provided in various ways including an 'else' branch
>> of an if-else-if chain.
>
> I think you are suggesting that [an explicit] "catch-all" should be
> given to make the compiler's job easier.  It maybe desirable from
> the point of view of controlling diagnostics but the result is less
> clear so I think it calls for a comment or even an assertion:
>
>   double sign(double x)
>   {
>         if (x <  0) return -1;
>         if (x == 0) return  0;
>         if (x >  0) return  1;
>         assert(isnan(x)); // all that's left...
>         return  x;
>   }

I agree with your sentiment about not worrying about making the
compiler's job easier.  For the code, though, I think it's better
to preserve the symmetry of the case tests, and put in a final
failure call - not to make the compiler's job easier, but to make
the intent more apparent to a human reader.  An assert() in place
of the final line would do the job instead, except that assert()
calls might be disabled by setting the macro NDEBUG.

  double sign(double x)
  {
        if (isnan(x)) return  x;
        if (x <  0  ) return -1;
        if (x == 0  ) return  0;
        if (x >  0  ) return  1;
        print_error_message_and_quit( "..whatever.." );
  }

Incidentally, putting the test for isnan(x) first allows the
function to work with signaling NaNs as well as quiet NaNs.
(I confess that I don't know if comparing a signaling NaN
to zero gives rise to a program exception.)

[toc] | [prev] | [next] | [standalone]


#175250

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2023-09-12 09:33 -0700
Message-ID<5e098055-c3bd-4f9c-984c-b4fdaf610adbn@googlegroups.com>
In reply to#175241
On Tuesday, 12 September 2023 at 16:17:18 UTC+1, Ben Bacarisse wrote:
> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
> 
> It is a mistake to link the error with the two behaviours. A single 
> error can provoke either or neither behaviour, sometimes always or 
> never. It's not uncommon for an error to go entirely unnoticed because 
> the behaviour is always correct. Maybe the fix is to put in "return 0;" 
> but that happens to be what is in this or that register on this C 
> implementation on this hardware at the point where the call happens. 
> 
> This is not quibbling or sophistry. The errors are in the text and the 
> behaviours are in the world. But We can only fix the text. That is the 
> only way a programmer can alter the behaviour.
>
That is a fair point. You can have an error which in fact never provokes incorrect
behaviour. For example to use sign() again, if we write it to return -1 or +1
and forget the zero, it might well aways return zero when it falls of the end 
for the case 0. It would be an error in the program text, but it would behave
correctly.  
>
> > I can't 
> > think of another behaviour that is erroneous but doesn't fall under 
> > one of those two categories (though someone might be able to suggest 
> > one).
> I can (timeliness comes to mind) but that would be quibbling. The big 
> issue is that I reject the notion that one error implies one of two 
> behaviours. 
> 
> Why does this matter? Because it's just programming. There should be a 
> specification where you have left a void for this mystery program. The 
> life support system should be specified to provide timely and correct 
> results to the oxygen valve or to stop in such a way to provoke other 
> systems to trigger the alarms other wise. 
>
It's specified to always control the flow of oxygen, based on various readings
it takes from sensors attached to the patient. If it stops controlling the flow
of oxygen, that's very serious. The alarm goes off. The nurse should come. 
But it's very much an emergency and undesired.   
> 
> Putting an abort() call and the end of sign(x) (if that is indeed what 
> you are suggesting) is called meeting the specification. Of course 
> there can be bugs (the call was missing at first) but that is just 
> programming. There are, of course, thousands of other fixes.
>
Not. it's not meeting the specification.
The code might look like this.

double sensor_value = readsensors();
if (sensor_value == NaN) /* the bug */
     handle_sensor_not_working();
else
{
     double delta_oxgyen = sign(sensor_value) * step;
     setoxygen(current_oxygen + delta_oxygen);
}

Now of course that should have been picked up in a code review.  Somehow that
didn't happen and it slipped through. 

So the specification is that if readsensors() return NaN, that means that the sensors
are not working, and we have recovery code to call that. But in fact it will not be called,
because the test has been miswritten.

> 
> > Now for some programs, no results are better than wrong 
> > results, for other programs, wrong results are better than no 
> > results. There are N! possibilities. N is 2, so there are 2! or 2 
> > types of program.
> This division can indeed be forced, but it's not a good one. A better 
> division is whether the program meets the spec or not. After all, that 
> is exactly what you are in effect calling for -- that all failures to 
> provide timely correct settings should be fatal errors.
>
Yes. For the life support machine. But not for the video game. 
> 
> > Thats one way you could generate a NaN.
> They are not magic. In the situation I described, where the floating 
> point numbers come from non-zero divisions of integers, you won't get 
> one. Of course someone could come along later and set 
> 
> double flow = 0.0/0.0; 
> 
> but that's just a bug like any other (except maybe much easier to spot). 
> Setting 
> 
> double flow = 1e-3; 
> 
> rather than 1e+3 is also a bug and needs to be caught. That the author 
> of sign(x) did not consider NaNs is no different to an author no 
> different considering a factor 10^6 error in the flow rate, except that 
> it's easier to avoid NaNs than it is to avoid simple typos.
>
sign() has a core domain which includes all the real numbers. You might know that
none of the reals in the program can be lower than unity. But you can't sensibly
trap such numbers and still call the function sign(). NaN isn't in the core domain.
We can sensibly say that sing(NaN) is NaN, or at a stretch, even 0. But we can
also say that calling sign with NaN is to be considered a programming error.
> 
> > You've been reading too much David Brown, and got infected. Anyone with 
> > any experience in programming knows that often bugs are very simple and 
> > obvious. Once you point them out. But highly qualified programmers still 
> > make such mistakes.
> I don't believe DB thinks what you believe he does. I certainly don't 
> think that. And I resent the notion that I have been "infected" by a 
> bad thought, especially one I am sure you have made up out of thin air. 
> Please acknowledge that I am perfectly aware that all programmers make 
> mistakes. Without that, there is simply no point in continuing. 
> 
Fair enough. Unlike some other posters, you don't look for opportuniites to snipe.
If you think the NaN comparison error is too simple, you can always think of a 
way to make it a bit more subtle whilst still being bascially the same bug.
Similar errors do make their way into critical systems where the costs are 
extremely high,  like spacecraft, and there have been reports.
>
> The issue, which you don't seem to be addressing, is what we do about 
> it. We don't just look at code and say, "that looks like a bug, let's 
> put an abort() in there". The whole software development process has to 
> be geared to minimising the ways in which a program text might fail to 
> behave as required. For some programs, the specification is to generate 
> correct results or to fail hard. For others it is to keep going at all 
> costs. 
> 
> One technique that can help (in one small area) is to try to ensure that 
> there are no NaNs. That can be simpler than putting in tests or other 
> actions all over the place in case one has just popped up like a genie 
> from a lamp. Note that I am not saying there can't be bugs, but I would 
> bet any money that a code review for "don't ever generate a NaN" is 
> easier and more effective than a code review for "check everywhere it 
> might matter for NaNs and act accordingly".
>
But in this case, readsensors() returns a NaN if the sensors have no data
(not working, or maybe not enough time lag between calls). That's a reasonable
interface. So we can't say "exclude all NaNs for the code". But a NaN still
shouldn't be passed to sign(). That's the programming error.
> 
> > No we can't use Haskell.
> That's a shame. The Glasgow Haskell compiler reports that in 
> 
> sign :: Double -> Int 
> sign x | x < 0 = -1 
> | x == 0 = 0 
> | x > 0 = 1 
> 
> the guards are non-exhaustive. 
> 
That's very good. 
 

[toc] | [prev] | [next] | [standalone]


#175252

Fromscott@slp53.sl.home (Scott Lurndal)
Date2023-09-12 16:48 +0000
Message-ID<DD0MM.39423$jJK6.35686@fx14.iad>
In reply to#175250
Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
>On Tuesday, 12 September 2023 at 16:17:18 UTC+1, Ben Bacarisse wrote:
>> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
>> 

>> I can (timeliness comes to mind) but that would be quibbling. The big 
>> issue is that I reject the notion that one error implies one of two 
>> behaviours. 
>> 
>> Why does this matter? Because it's just programming. There should be a 
>> specification where you have left a void for this mystery program. The 
>> life support system should be specified to provide timely and correct 
>> results to the oxygen valve or to stop in such a way to provoke other 
>> systems to trigger the alarms other wise. 
>>
>It's specified to always control the flow of oxygen, based on various readings
>it takes from sensors attached to the patient.

Isn't that what Ben just wrote?

>> 
>> Putting an abort() call and the end of sign(x) (if that is indeed what 
>> you are suggesting) is called meeting the specification. Of course 
>> there can be bugs (the call was missing at first) but that is just 
>> programming. There are, of course, thousands of other fixes.
>>
>Not. it's not meeting the specification.
>The code might look like this.

>double sensor_value = readsensors();

I sure hope not.  There's no need to use floating point
in this case.    The flow-rate is in units of O2 per unit time.

e.g  milliliters per millisecond.

If you need higher resolution, microliters per microsecond.

In both cases, they're simple integers well within the
range of a 32-bit unsigned integer and there will never
be a NaN.

[toc] | [prev] | [next] | [standalone]


#175267

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2023-09-12 10:57 -0700
Message-ID<647ac7a4-fb14-4072-b65f-5b20290a4b7bn@googlegroups.com>
In reply to#175252
On Tuesday, 12 September 2023 at 17:48:52 UTC+1, Scott Lurndal wrote:
> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
> >On Tuesday, 12 September 2023 at 16:17:18 UTC+1, Ben Bacarisse wrote: 
> >> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
> >> 
> 
> >> I can (timeliness comes to mind) but that would be quibbling. The big 
> >> issue is that I reject the notion that one error implies one of two 
> >> behaviours. 
> >> 
> >> Why does this matter? Because it's just programming. There should be a 
> >> specification where you have left a void for this mystery program. The 
> >> life support system should be specified to provide timely and correct 
> >> results to the oxygen valve or to stop in such a way to provoke other 
> >> systems to trigger the alarms other wise. 
> >> 
> >It's specified to always control the flow of oxygen, based on various readings 
> >it takes from sensors attached to the patient.
> Isn't that what Ben just wrote?
> >> 
> >> Putting an abort() call and the end of sign(x) (if that is indeed what 
> >> you are suggesting) is called meeting the specification. Of course 
> >> there can be bugs (the call was missing at first) but that is just 
> >> programming. There are, of course, thousands of other fixes. 
> >> 
> >Not. it's not meeting the specification. 
> >The code might look like this. 
> 
> >double sensor_value = readsensors();
> I sure hope not. There's no need to use floating point 
> in this case. The flow-rate is in units of O2 per unit time. 
> 
> e.g milliliters per millisecond. 
> 
> If you need higher resolution, microliters per microsecond. 
> 
> In both cases, they're simple integers well within the 
> range of a 32-bit unsigned integer and there will never 
> be a NaN.
>
So what happens if the sensor doesn't give a reading?

[toc] | [prev] | [next] | [standalone]


#175268

Fromscott@slp53.sl.home (Scott Lurndal)
Date2023-09-12 18:07 +0000
Message-ID<KN1MM.6185$Q73f.3452@fx48.iad>
In reply to#175267
Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
>On Tuesday, 12 September 2023 at 17:48:52 UTC+1, Scott Lurndal wrote:
>> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
>> >On Tuesday, 12 September 2023 at 16:17:18 UTC+1, Ben Bacarisse wrote: 
>> >> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
>> >> 
>> 
>> >> I can (timeliness comes to mind) but that would be quibbling. The big 
>> >> issue is that I reject the notion that one error implies one of two 
>> >> behaviours. 
>> >> 
>> >> Why does this matter? Because it's just programming. There should be a 
>> >> specification where you have left a void for this mystery program. The 
>> >> life support system should be specified to provide timely and correct 
>> >> results to the oxygen valve or to stop in such a way to provoke other 
>> >> systems to trigger the alarms other wise. 
>> >> 
>> >It's specified to always control the flow of oxygen, based on various readings 
>> >it takes from sensors attached to the patient.
>> Isn't that what Ben just wrote?
>> >> 
>> >> Putting an abort() call and the end of sign(x) (if that is indeed what 
>> >> you are suggesting) is called meeting the specification. Of course 
>> >> there can be bugs (the call was missing at first) but that is just 
>> >> programming. There are, of course, thousands of other fixes. 
>> >> 
>> >Not. it's not meeting the specification. 
>> >The code might look like this. 
>> 
>> >double sensor_value = readsensors();
>> I sure hope not. There's no need to use floating point 
>> in this case. The flow-rate is in units of O2 per unit time. 
>> 
>> e.g milliliters per millisecond. 
>> 
>> If you need higher resolution, microliters per microsecond. 
>> 
>> In both cases, they're simple integers well within the 
>> range of a 32-bit unsigned integer and there will never 
>> be a NaN.
>>
>So what happens if the sensor doesn't give a reading?

Whatever the design document for the O2 sensor requirements
specifies.

I would assume that the designer would anticipate such a
condition and the function that obtains the sensor reading
would indicate a failure condition that would be handled
according to the design specification.  There is no need
to use a NaN for that, there are dozens of alternatives.

[toc] | [prev] | [next] | [standalone]


#175280

FromDavid Brown <david.brown@hesbynett.no>
Date2023-09-12 21:23 +0200
Message-ID<udqdr6$1milh$2@dont-email.me>
In reply to#175268
On 12/09/2023 20:07, Scott Lurndal wrote:
> Malcolm McLean <malcolm.arthur.mclean@gmail.com> writes:
>> On Tuesday, 12 September 2023 at 17:48:52 UTC+1, Scott Lurndal wrote:
>>> Malcolm McLean <malcolm.ar...@gmail.com> writes:
>>>> On Tuesday, 12 September 2023 at 16:17:18 UTC+1, Ben Bacarisse wrote:
>>>>> Malcolm McLean <malcolm.ar...@gmail.com> writes:
>>>>>
>>>
>>>>> I can (timeliness comes to mind) but that would be quibbling. The big
>>>>> issue is that I reject the notion that one error implies one of two
>>>>> behaviours.
>>>>>
>>>>> Why does this matter? Because it's just programming. There should be a
>>>>> specification where you have left a void for this mystery program. The
>>>>> life support system should be specified to provide timely and correct
>>>>> results to the oxygen valve or to stop in such a way to provoke other
>>>>> systems to trigger the alarms other wise.
>>>>>
>>>> It's specified to always control the flow of oxygen, based on various readings
>>>> it takes from sensors attached to the patient.
>>> Isn't that what Ben just wrote?
>>>>>
>>>>> Putting an abort() call and the end of sign(x) (if that is indeed what
>>>>> you are suggesting) is called meeting the specification. Of course
>>>>> there can be bugs (the call was missing at first) but that is just
>>>>> programming. There are, of course, thousands of other fixes.
>>>>>
>>>> Not. it's not meeting the specification.
>>>> The code might look like this.
>>>
>>>> double sensor_value = readsensors();
>>> I sure hope not. There's no need to use floating point
>>> in this case. The flow-rate is in units of O2 per unit time.
>>>
>>> e.g milliliters per millisecond.
>>>
>>> If you need higher resolution, microliters per microsecond.
>>>
>>> In both cases, they're simple integers well within the
>>> range of a 32-bit unsigned integer and there will never
>>> be a NaN.
>>>
>> So what happens if the sensor doesn't give a reading?
> 
> Whatever the design document for the O2 sensor requirements
> specifies.
> 
> I would assume that the designer would anticipate such a
> condition and the function that obtains the sensor reading
> would indicate a failure condition that would be handled
> according to the design specification.  There is no need
> to use a NaN for that, there are dozens of alternatives.

A common standard for sensors is to provide a 4 to 20 mA output for the 
signal.  That leaves 0 mA to indicate disconnected, and a value of 
perhaps 1 mA to indicate a fault.  That is, of course, at electrical 
interface, but the same principles can be used in software, such as a 
value of 0 to 1000 for valid readings and -1 for invalid readings.

And as you say, there are /many/ ways to do this.  In C++, I might have 
the readsensors() function return a std::optional<oxygen_ml_per_sec_t> 
to make it easy to see when there is a valid value.  In C, it would 
perhaps be a struct with a bool "valid" flag.  It's also common to have 
such functions take a pointer-to-result parameter and return a status flag.

But I would not be returning either a double or an integer type - it 
would be a specific type, whose name included the units, to make it as 
difficult as possible to make a mistake.


[toc] | [prev] | [next] | [standalone]


#175348

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2023-09-13 02:07 -0700
Message-ID<16d2ead0-48b5-4b73-9bec-03073d98d9d3n@googlegroups.com>
In reply to#175280
On Tuesday, 12 September 2023 at 20:23:32 UTC+1, David Brown wrote:
> On 12/09/2023 20:07, Scott Lurndal wrote: 
>
> > I would assume that the designer would anticipate such a 
> > condition and the function that obtains the sensor reading 
> > would indicate a failure condition that would be handled 
> > according to the design specification. There is no need 
> > to use a NaN for that, there are dozens of alternatives.
> A common standard for sensors is to provide a 4 to 20 mA output for the 
> signal. That leaves 0 mA to indicate disconnected, and a value of 
> perhaps 1 mA to indicate a fault. That is, of course, at electrical 
> interface, but the same principles can be used in software, such as a 
> value of 0 to 1000 for valid readings and -1 for invalid readings. 
>
I don't do embedded programming (I have dabbled, but nothing serious).
But in most software engineering contexts, you would want to abstract
away the result of a call to readsensors() from the physical details of
how the sensors work. 
>
> And as you say, there are /many/ ways to do this. In C++, I might have 
> the readsensors() function return a std::optional<oxygen_ml_per_sec_t> 
> to make it easy to see when there is a valid value. In C, it would 
> perhaps be a struct with a bool "valid" flag. It's also common to have 
> such functions take a pointer-to-result parameter and return a status flag. 
> 
> But I would not be returning either a double or an integer type - it 
> would be a specific type, whose name included the units, to make it as 
> difficult as possible to make a mistake.
>
There's no way of attaching units to C variables, but one way is to use
types. But in large programs that can cause problems because the types
will usually only support the four rules of arithemetic. So the usual solution 
is to use SI units. So a flow would be litres per second, not ml per second.
(So you do need a decent range and prescision, because the values might
very quite high or quite low in relation to the units).

[toc] | [prev] | [next] | [standalone]


#175359

FromDavid Brown <david.brown@hesbynett.no>
Date2023-09-13 12:43 +0200
Message-ID<uds3o7$23bp5$1@dont-email.me>
In reply to#175348
On 13/09/2023 11:07, Malcolm McLean wrote:
> On Tuesday, 12 September 2023 at 20:23:32 UTC+1, David Brown wrote:
>> On 12/09/2023 20:07, Scott Lurndal wrote:
>>
>>> I would assume that the designer would anticipate such a
>>> condition and the function that obtains the sensor reading
>>> would indicate a failure condition that would be handled
>>> according to the design specification. There is no need
>>> to use a NaN for that, there are dozens of alternatives.
>> A common standard for sensors is to provide a 4 to 20 mA output for the
>> signal. That leaves 0 mA to indicate disconnected, and a value of
>> perhaps 1 mA to indicate a fault. That is, of course, at electrical
>> interface, but the same principles can be used in software, such as a
>> value of 0 to 1000 for valid readings and -1 for invalid readings.
>>
> I don't do embedded programming (I have dabbled, but nothing serious).
> But in most software engineering contexts, you would want to abstract
> away the result of a call to readsensors() from the physical details of
> how the sensors work.

Agreed.  But the type of abstraction is going to be very variable 
depending on the kind of code, and the part of the code you are working 
on at the time.  A double might be a reasonable choice for a sensor 
value in simple cases where you know everything is fine - it would not 
be a suitable type for tracking failures or possible uncertainties in a 
measurement.

>>
>> And as you say, there are /many/ ways to do this. In C++, I might have
>> the readsensors() function return a std::optional<oxygen_ml_per_sec_t>
>> to make it easy to see when there is a valid value. In C, it would
>> perhaps be a struct with a bool "valid" flag. It's also common to have
>> such functions take a pointer-to-result parameter and return a status flag.
>>
>> But I would not be returning either a double or an integer type - it
>> would be a specific type, whose name included the units, to make it as
>> difficult as possible to make a mistake.
>>
> There's no way of attaching units to C variables, but one way is to use
> types. 

You contradict yourself.  There /is/ a way of attaching units to C 
variables - you use types, as I said above.

You can also use good naming practices.  Having a double called 
"oxygen_ml_per_sec", rather than "oxygen_rate", attaches a unit to the 
variable.  The compiler can't check the units by name, but at least 
human readers can do so.

> But in large programs that can cause problems because the types
> will usually only support the four rules of arithemetic. 

You are jumbling concepts again, and imagining things.  (Again, I would 
encourage you to use Wikipedia whenever you want to use the word "the". 
Look up "The Four Rules of Arithmetic" on Wikipedia - there is no such 
thing.  It's all in your mind, and it really does not help the 
conversation at all.)

> So the usual solution
> is to use SI units. So a flow would be litres per second, not ml per second.
> (So you do need a decent range and prescision, because the values might
> very quite high or quite low in relation to the units).

Doubles in SI units can be a good choice in many cases, yes.  But you 
can do better in C - and if the code is safety-critical, such as this 
case, you /should/ do better.  Wrap the value in a struct, then the type 
safety rules of C will stop you making mistakes.  The types are more 
awkward to use, of course - you have to use member access or specific 
functions to access the actual values or do arithmetic on them.  That is 
a price worth paying for safety.  (Alternatively, you use a language 
that has better support for such things, like C++ or Ada.)

The bigger the program, the more important this kind of thing is - you 
do not skimp on appropriate levels of safety just because the code base 
is large.


[toc] | [prev] | [next] | [standalone]


#175373

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2023-09-13 04:04 -0700
Message-ID<50612481-bb86-4ab8-afe3-c4e88b14fb2fn@googlegroups.com>
In reply to#175359
On Wednesday, 13 September 2023 at 11:43:34 UTC+1, David Brown wrote:
> On 13/09/2023 11:07, Malcolm McLean wrote: 
> > On Tuesday, 12 September 2023 at 20:23:32 UTC+1, David Brown wrote: 
> >> On 12/09/2023 20:07, Scott Lurndal wrote: 
> >> 
> >>> I would assume that the designer would anticipate such a 
> >>> condition and the function that obtains the sensor reading 
> >>> would indicate a failure condition that would be handled 
> >>> according to the design specification. There is no need 
> >>> to use a NaN for that, there are dozens of alternatives. 
> >> A common standard for sensors is to provide a 4 to 20 mA output for the 
> >> signal. That leaves 0 mA to indicate disconnected, and a value of 
> >> perhaps 1 mA to indicate a fault. That is, of course, at electrical 
> >> interface, but the same principles can be used in software, such as a 
> >> value of 0 to 1000 for valid readings and -1 for invalid readings. 
> >> 
> > I don't do embedded programming (I have dabbled, but nothing serious). 
> > But in most software engineering contexts, you would want to abstract 
> > away the result of a call to readsensors() from the physical details of 
> > how the sensors work.
> Agreed. But the type of abstraction is going to be very variable 
> depending on the kind of code, and the part of the code you are working 
> on at the time. A double might be a reasonable choice for a sensor 
> value in simple cases where you know everything is fine - it would not 
> be a suitable type for tracking failures or possible uncertainties in a 
> measurement.
> >> 
> >> And as you say, there are /many/ ways to do this. In C++, I might have 
> >> the readsensors() function return a std::optional<oxygen_ml_per_sec_t> 
> >> to make it easy to see when there is a valid value. In C, it would 
> >> perhaps be a struct with a bool "valid" flag. It's also common to have 
> >> such functions take a pointer-to-result parameter and return a status flag. 
> >> 
> >> But I would not be returning either a double or an integer type - it 
> >> would be a specific type, whose name included the units, to make it as 
> >> difficult as possible to make a mistake. 
> >> 
> > There's no way of attaching units to C variables, but one way is to use 
> > types.
> You contradict yourself. There /is/ a way of attaching units to C 
> variables - you use types, as I said above. 
> 
> You can also use good naming practices. Having a double called 
> "oxygen_ml_per_sec", rather than "oxygen_rate", attaches a unit to the 
> variable. The compiler can't check the units by name, but at least 
> human readers can do so.
> > But in large programs that can cause problems because the types 
> > will usually only support the four rules of arithemetic.
> You are jumbling concepts again, and imagining things. (Again, I would 
> encourage you to use Wikipedia whenever you want to use the word "the". 
> Look up "The Four Rules of Arithmetic" on Wikipedia - there is no such 
> thing. It's all in your mind, and it really does not help the 
> conversation at all.)
> > So the usual solution 
> > is to use SI units. So a flow would be litres per second, not ml per second. 
> > (So you do need a decent range and prescision, because the values might 
> > very quite high or quite low in relation to the units).
> Doubles in SI units can be a good choice in many cases, yes. But you 
> can do better in C - and if the code is safety-critical, such as this 
> case, you /should/ do better. Wrap the value in a struct, then the type 
> safety rules of C will stop you making mistakes. The types are more 
> awkward to use, of course - you have to use member access or specific 
> functions to access the actual values or do arithmetic on them. That is 
> a price worth paying for safety. (Alternatively, you use a language 
> that has better support for such things, like C++ or Ada.) 
> 
> The bigger the program, the more important this kind of thing is - you 
> do not skimp on appropriate levels of safety just because the code base 
> is large.
>
The techniques you are advocating will work only if the program is doing something
relatively simple. 
They won't scale up to, for example, a statistical analysis of the oxygen flow.
Because as you say "The types are more  awkward to use, of course - you have 
to use member access or specific  functions to access the actual values or do 
arithmetic on them.". All your carefully written and debugged statistical functions
would have to be totally rewritten to accept the structures. Which for a life support
system you could probably do, as money is literally no object, but not for something
with cost constraints.
C++ templates can come to the rescue here. But they come with their own safety
problems. Because you don't know the range or precision of the types, it can be
much harder to test a templated function.

[toc] | [prev] | [next] | [standalone]


#175382

FromDavid Brown <david.brown@hesbynett.no>
Date2023-09-13 14:07 +0200
Message-ID<uds8le$2470c$1@dont-email.me>
In reply to#175373
On 13/09/2023 13:04, Malcolm McLean wrote:
> On Wednesday, 13 September 2023 at 11:43:34 UTC+1, David Brown wrote:
>> On 13/09/2023 11:07, Malcolm McLean wrote:
>>> On Tuesday, 12 September 2023 at 20:23:32 UTC+1, David Brown wrote:
>>>> On 12/09/2023 20:07, Scott Lurndal wrote:
>>>>
>>>>> I would assume that the designer would anticipate such a
>>>>> condition and the function that obtains the sensor reading
>>>>> would indicate a failure condition that would be handled
>>>>> according to the design specification. There is no need
>>>>> to use a NaN for that, there are dozens of alternatives.
>>>> A common standard for sensors is to provide a 4 to 20 mA output for the
>>>> signal. That leaves 0 mA to indicate disconnected, and a value of
>>>> perhaps 1 mA to indicate a fault. That is, of course, at electrical
>>>> interface, but the same principles can be used in software, such as a
>>>> value of 0 to 1000 for valid readings and -1 for invalid readings.
>>>>
>>> I don't do embedded programming (I have dabbled, but nothing serious).
>>> But in most software engineering contexts, you would want to abstract
>>> away the result of a call to readsensors() from the physical details of
>>> how the sensors work.
>> Agreed. But the type of abstraction is going to be very variable
>> depending on the kind of code, and the part of the code you are working
>> on at the time. A double might be a reasonable choice for a sensor
>> value in simple cases where you know everything is fine - it would not
>> be a suitable type for tracking failures or possible uncertainties in a
>> measurement.
>>>>
>>>> And as you say, there are /many/ ways to do this. In C++, I might have
>>>> the readsensors() function return a std::optional<oxygen_ml_per_sec_t>
>>>> to make it easy to see when there is a valid value. In C, it would
>>>> perhaps be a struct with a bool "valid" flag. It's also common to have
>>>> such functions take a pointer-to-result parameter and return a status flag.
>>>>
>>>> But I would not be returning either a double or an integer type - it
>>>> would be a specific type, whose name included the units, to make it as
>>>> difficult as possible to make a mistake.
>>>>
>>> There's no way of attaching units to C variables, but one way is to use
>>> types.
>> You contradict yourself. There /is/ a way of attaching units to C
>> variables - you use types, as I said above.
>>
>> You can also use good naming practices. Having a double called
>> "oxygen_ml_per_sec", rather than "oxygen_rate", attaches a unit to the
>> variable. The compiler can't check the units by name, but at least
>> human readers can do so.
>>> But in large programs that can cause problems because the types
>>> will usually only support the four rules of arithemetic.
>> You are jumbling concepts again, and imagining things. (Again, I would
>> encourage you to use Wikipedia whenever you want to use the word "the".
>> Look up "The Four Rules of Arithmetic" on Wikipedia - there is no such
>> thing. It's all in your mind, and it really does not help the
>> conversation at all.)
>>> So the usual solution
>>> is to use SI units. So a flow would be litres per second, not ml per second.
>>> (So you do need a decent range and prescision, because the values might
>>> very quite high or quite low in relation to the units).
>> Doubles in SI units can be a good choice in many cases, yes. But you
>> can do better in C - and if the code is safety-critical, such as this
>> case, you /should/ do better. Wrap the value in a struct, then the type
>> safety rules of C will stop you making mistakes. The types are more
>> awkward to use, of course - you have to use member access or specific
>> functions to access the actual values or do arithmetic on them. That is
>> a price worth paying for safety. (Alternatively, you use a language
>> that has better support for such things, like C++ or Ada.)
>>
>> The bigger the program, the more important this kind of thing is - you
>> do not skimp on appropriate levels of safety just because the code base
>> is large.
>>
> The techniques you are advocating will work only if the program is doing something
> relatively simple.
> They won't scale up to, for example, a statistical analysis of the oxygen flow.
> Because as you say "The types are more  awkward to use, of course - you have
> to use member access or specific  functions to access the actual values or do
> arithmetic on them.". All your carefully written and debugged statistical functions
> would have to be totally rewritten to accept the structures. Which for a life support
> system you could probably do, as money is literally no object, but not for something
> with cost constraints.

How you code things depends on the task at hand.  For an oxygen 
regulation system, safety is likely to be top priority - costs and 
development time are far less important than confidence in the 
correctness of the system.  Other systems have different balances.

When you have an important control system like this, the most important 
design decisions at the start are about how the system is split up and 
modularised.  Then you handle the appropriate tasks in the appropriate 
place.

Thus it doesn't matter if the safe types used for oxygen regulation fit 
badly with statistical analysis - you don't do statistical analysis on 
the system that handles oxygen regulation.

You would have, for example, a dedicated microcontroller-based oxygen 
regulator doing nothing but oxygen regulation.  The desired flow rate 
comes in on a simple interface (such as a serial link - no Ethernet, 
USB, or other advanced connection), and information about current rates 
go out on a similar link.  Alarms are connected directly to lights, 
sirens, and so on, as well as being passed on through the link.  The 
board here is independent, with its own battery backup.  All the code is 
written in carefully restricted subsets of C, C++ or Ada, according to 
SIL standards, with all the paperwork, reviews, testing, and 
documentation needed.

At the other end of the link is an embedded Linux system with 
networking, a screen, a user interface, and so on - and whatever 
statistical analysis you want.  It is written in a combination of C, 
C++, Python, R, PHP, Eiffel, Haskell, and whatever else suits.  It's a 
different world entirely.


The last thing you would want to do is reduce the quality or safety 
controls on the regulator just so that you can "scale" it to fit with 
some statistics package you found!


> C++ templates can come to the rescue here. But they come with their own safety
> problems. Because you don't know the range or precision of the types, it can be
> much harder to test a templated function.
> 

C++ templates /do/ have their own testing challenges, yes.  But C++ can 
certainly make it a lot easier to write safe code for this kind of 
thing.  (It can also give you scope to write incomprehensible and 
untestable code - safety-critical systems always use restricted subsets 
of languages.)  But you still keep the parts separate, even if you use 
C++ on both parts.


[toc] | [prev] | [next] | [standalone]


#175347

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2023-09-13 01:47 -0700
Message-ID<1ad9d75b-48bb-4b3a-93f0-92900479280en@googlegroups.com>
In reply to#175268
On Tuesday, 12 September 2023 at 19:07:54 UTC+1, Scott Lurndal wrote:
> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
> >On Tuesday, 12 September 2023 at 17:48:52 UTC+1, Scott Lurndal wrote: 
> >> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
> >> >On Tuesday, 12 September 2023 at 16:17:18 UTC+1, Ben Bacarisse wrote: 
> >> >> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
> >> >> 
> >> 
> >> >> I can (timeliness comes to mind) but that would be quibbling. The big 
> >> >> issue is that I reject the notion that one error implies one of two 
> >> >> behaviours. 
> >> >> 
> >> >> Why does this matter? Because it's just programming. There should be a 
> >> >> specification where you have left a void for this mystery program. The 
> >> >> life support system should be specified to provide timely and correct 
> >> >> results to the oxygen valve or to stop in such a way to provoke other 
> >> >> systems to trigger the alarms other wise. 
> >> >> 
> >> >It's specified to always control the flow of oxygen, based on various readings 
> >> >it takes from sensors attached to the patient. 
> >> Isn't that what Ben just wrote? 
> >> >> 
> >> >> Putting an abort() call and the end of sign(x) (if that is indeed what 
> >> >> you are suggesting) is called meeting the specification. Of course 
> >> >> there can be bugs (the call was missing at first) but that is just 
> >> >> programming. There are, of course, thousands of other fixes. 
> >> >> 
> >> >Not. it's not meeting the specification. 
> >> >The code might look like this. 
> >> 
> >> >double sensor_value = readsensors(); 
> >> I sure hope not. There's no need to use floating point 
> >> in this case. The flow-rate is in units of O2 per unit time. 
> >> 
> >> e.g milliliters per millisecond. 
> >> 
> >> If you need higher resolution, microliters per microsecond. 
> >> 
> >> In both cases, they're simple integers well within the 
> >> range of a 32-bit unsigned integer and there will never 
> >> be a NaN. 
> >> 
> >So what happens if the sensor doesn't give a reading?
> Whatever the design document for the O2 sensor requirements 
> specifies. 
>
Most devices attached to microprocessors do put bits on the bus
which represent fixed-point values. But this is a higher level function
which is reading one or more sensors, and then combining the results
into a single return value (you might have several sensors and it is
taking an average). If the processor supports floating point, there's no
particular reason not to use it, and to keep everything in the physical 
sensor's fixed point format which you read in at a low level.
>
> I would assume that the designer would anticipate such a 
> condition and the function that obtains the sensor reading 
> would indicate a failure condition that would be handled 
> according to the design specification. There is no need 
> to use a NaN for that, there are dozens of alternatives.
>
So an alternative would be

/* return sensor reading in 16:16 fixed point format, INT_MAX for
sensor fail */
sint32_t readsensors();

So what have we done? We got an informally specified NaN. INT_MAX
is "not a number" in this context. 

Another would be
sint32_t readsensors(bool *hasdata);

Now hasdata indicates that the return is not a number when it is false. This
is better as it isn't informlly specified and much less likely to be misunderstood.
But all you are achieving is to move the NaN representation out of the return 
value and into a flag. You still have a not a number value, and there's still the
risk that it will be used as a real value.

Which to be fair, there is still with a floating point NaN, as my bug indicated.
However you have to be pretty unlucky (NaN is generated, treated as a number,
then passed to a function which returns a number when passed NaN).

I'm not saying that the inferface which says "return the sensor result as a real
in natural (well, SI) units, and NaN if there is no data" is necessarily the very best 
that could be devised. But it's unexceptional. 

[toc] | [prev] | [next] | [standalone]


#175372

FromDavid Brown <david.brown@hesbynett.no>
Date2023-09-13 13:02 +0200
Message-ID<uds4rb$23he0$1@dont-email.me>
In reply to#175347
On 13/09/2023 10:47, Malcolm McLean wrote:
> On Tuesday, 12 September 2023 at 19:07:54 UTC+1, Scott Lurndal wrote:
>> Malcolm McLean <malcolm.ar...@gmail.com> writes:
>>> On Tuesday, 12 September 2023 at 17:48:52 UTC+1, Scott Lurndal wrote:
>>>> Malcolm McLean <malcolm.ar...@gmail.com> writes:
>>>>> On Tuesday, 12 September 2023 at 16:17:18 UTC+1, Ben Bacarisse wrote:
>>>>>> Malcolm McLean <malcolm.ar...@gmail.com> writes:
>>>>>>
>>>>
>>>>>> I can (timeliness comes to mind) but that would be quibbling. The big
>>>>>> issue is that I reject the notion that one error implies one of two
>>>>>> behaviours.
>>>>>>
>>>>>> Why does this matter? Because it's just programming. There should be a
>>>>>> specification where you have left a void for this mystery program. The
>>>>>> life support system should be specified to provide timely and correct
>>>>>> results to the oxygen valve or to stop in such a way to provoke other
>>>>>> systems to trigger the alarms other wise.
>>>>>>
>>>>> It's specified to always control the flow of oxygen, based on various readings
>>>>> it takes from sensors attached to the patient.
>>>> Isn't that what Ben just wrote?
>>>>>>
>>>>>> Putting an abort() call and the end of sign(x) (if that is indeed what
>>>>>> you are suggesting) is called meeting the specification. Of course
>>>>>> there can be bugs (the call was missing at first) but that is just
>>>>>> programming. There are, of course, thousands of other fixes.
>>>>>>
>>>>> Not. it's not meeting the specification.
>>>>> The code might look like this.
>>>>
>>>>> double sensor_value = readsensors();
>>>> I sure hope not. There's no need to use floating point
>>>> in this case. The flow-rate is in units of O2 per unit time.
>>>>
>>>> e.g milliliters per millisecond.
>>>>
>>>> If you need higher resolution, microliters per microsecond.
>>>>
>>>> In both cases, they're simple integers well within the
>>>> range of a 32-bit unsigned integer and there will never
>>>> be a NaN.
>>>>
>>> So what happens if the sensor doesn't give a reading?
>> Whatever the design document for the O2 sensor requirements
>> specifies.
>>
> Most devices attached to microprocessors do put bits on the bus
> which represent fixed-point values. But this is a higher level function
> which is reading one or more sensors, and then combining the results
> into a single return value (you might have several sensors and it is
> taking an average). If the processor supports floating point, there's no
> particular reason not to use it, and to keep everything in the physical
> sensor's fixed point format which you read in at a low level.
>>
>> I would assume that the designer would anticipate such a
>> condition and the function that obtains the sensor reading
>> would indicate a failure condition that would be handled
>> according to the design specification. There is no need
>> to use a NaN for that, there are dozens of alternatives.
>>
> So an alternative would be
> 
> /* return sensor reading in 16:16 fixed point format, INT_MAX for
> sensor fail */
> sint32_t readsensors();
> 

typedef int32_t Q15_16_t;
static const Q15_16_t sensor_fail = (Q15_16_t) 0x80000000;

Q15_16_t x = read_sensors();
if (x == sensor_fail) {
	...
} else {
	...
}

"sint32_t" would be assumed to be an alias for "int32_t".  If you mean a 
fixed point format, the most common practice is the Q format.


> So what have we done? We got an informally specified NaN. INT_MAX
> is "not a number" in this context.

Yes, it is all explicit.  It is not "informally" specified, unless 
you've failed to make the specification clear.  If it is there in the 
code and documentation, it is "formally" specified.

> 
> Another would be
> sint32_t readsensors(bool *hasdata);

Or, in the ordering used by virtually all C code in such cases,

	bool read_sensors(sint32_t * sensor_value);

Or what is more common, and more useful, return a status code that is an 
enumerated type indicating the success or type of error.

(I personally find it more intuitive to return a struct of status and 
value, rather than have some return information by pointer parameter, 
but that's just my own style.)

> 
> Now hasdata indicates that the return is not a number when it is false. This
> is better as it isn't informlly specified and much less likely to be misunderstood.

I do agree that a boolean or other status indicator is often a better 
choice, because you are less likely to get it wrong (even though it is 
no more and no less "formally" or "informally" specified).

Alternatively, the return value can be within a struct, and then the 
access functions would make it very difficult to use incorrectly.

> But all you are achieving is to move the NaN representation out of the return
> value and into a flag. You still have a not a number value, and there's still the
> risk that it will be used as a real value.

There is no way to make a system so foolproof that no fool can get it 
wrong.  But the suggestions here so far make it a /lot/ harder to get 
wrong than using floating point NaN's.

> 
> Which to be fair, there is still with a floating point NaN, as my bug indicated.
> However you have to be pretty unlucky (NaN is generated, treated as a number,
> then passed to a function which returns a number when passed NaN).
> 
> I'm not saying that the inferface which says "return the sensor result as a real
> in natural (well, SI) units, and NaN if there is no data" is necessarily the very best
> that could be devised. But it's unexceptional.
> 

And I am not saying it is not unusable as a choice - I am just saying it 
is a bad choice compared to many alternatives, and not one I would ever 
consider in my work.  It's easy to get /so/ much better.

(I have worked on safety-critical systems, where failure, in extreme 
cases, could result in death.  Most of my work is not that critical, 
however.)

[toc] | [prev] | [next] | [standalone]


#175378

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2023-09-13 04:45 -0700
Message-ID<e837db60-7ae9-4aa6-b539-424b97579e4dn@googlegroups.com>
In reply to#175372
On Wednesday, 13 September 2023 at 12:02:44 UTC+1, David Brown wrote:
> On 13/09/2023 10:47, Malcolm McLean wrote: 
> > On Tuesday, 12 September 2023 at 19:07:54 UTC+1, Scott Lurndal wrote: 
> >> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
> >>> On Tuesday, 12 September 2023 at 17:48:52 UTC+1, Scott Lurndal wrote: 
> >>>> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
> >>>>> On Tuesday, 12 September 2023 at 16:17:18 UTC+1, Ben Bacarisse wrote: 
> >>>>>> Malcolm McLean <malcolm.ar...@gmail.com> writes: 
> >>>>>> 
> >>>> 
> >>>>>> I can (timeliness comes to mind) but that would be quibbling. The big 
> >>>>>> issue is that I reject the notion that one error implies one of two 
> >>>>>> behaviours. 
> >>>>>> 
> >>>>>> Why does this matter? Because it's just programming. There should be a 
> >>>>>> specification where you have left a void for this mystery program. The 
> >>>>>> life support system should be specified to provide timely and correct 
> >>>>>> results to the oxygen valve or to stop in such a way to provoke other 
> >>>>>> systems to trigger the alarms other wise. 
> >>>>>> 
> >>>>> It's specified to always control the flow of oxygen, based on various readings 
> >>>>> it takes from sensors attached to the patient. 
> >>>> Isn't that what Ben just wrote? 
> >>>>>> 
> >>>>>> Putting an abort() call and the end of sign(x) (if that is indeed what 
> >>>>>> you are suggesting) is called meeting the specification. Of course 
> >>>>>> there can be bugs (the call was missing at first) but that is just 
> >>>>>> programming. There are, of course, thousands of other fixes. 
> >>>>>> 
> >>>>> Not. it's not meeting the specification. 
> >>>>> The code might look like this. 
> >>>> 
> >>>>> double sensor_value = readsensors(); 
> >>>> I sure hope not. There's no need to use floating point 
> >>>> in this case. The flow-rate is in units of O2 per unit time. 
> >>>> 
> >>>> e.g milliliters per millisecond. 
> >>>> 
> >>>> If you need higher resolution, microliters per microsecond. 
> >>>> 
> >>>> In both cases, they're simple integers well within the 
> >>>> range of a 32-bit unsigned integer and there will never 
> >>>> be a NaN. 
> >>>> 
> >>> So what happens if the sensor doesn't give a reading? 
> >> Whatever the design document for the O2 sensor requirements 
> >> specifies. 
> >> 
> > Most devices attached to microprocessors do put bits on the bus 
> > which represent fixed-point values. But this is a higher level function 
> > which is reading one or more sensors, and then combining the results 
> > into a single return value (you might have several sensors and it is 
> > taking an average). If the processor supports floating point, there's no 
> > particular reason not to use it, and to keep everything in the physical 
> > sensor's fixed point format which you read in at a low level. 
> >> 
> >> I would assume that the designer would anticipate such a 
> >> condition and the function that obtains the sensor reading 
> >> would indicate a failure condition that would be handled 
> >> according to the design specification. There is no need 
> >> to use a NaN for that, there are dozens of alternatives. 
> >> 
> > So an alternative would be 
> > 
> > /* return sensor reading in 16:16 fixed point format, INT_MAX for 
> > sensor fail */ 
> > sint32_t readsensors(); 
> >
> typedef int32_t Q15_16_t; 
> static const Q15_16_t sensor_fail = (Q15_16_t) 0x80000000; 
> 
> Q15_16_t x = read_sensors(); 
> if (x == sensor_fail) { 
> ... 
> } else { 
> ... 
> } 
> 
> "sint32_t" would be assumed to be an alias for "int32_t". If you mean a 
> fixed point format, the most common practice is the Q format.
> > So what have we done? We got an informally specified NaN. INT_MAX 
> > is "not a number" in this context.
> Yes, it is all explicit. It is not "informally" specified, unless 
> you've failed to make the specification clear. If it is there in the 
> code and documentation, it is "formally" specified.
> 
Scott said "we have no NaNs". But what he meant was that we have no
NaNs as formally specified by IEEE. We still have representations which 
indicate that a varibale doesn't hold a number. But because he hasn't called
them "not a number representations" in a formal way, they are "informally
specified".  
 If the sensor doesn't return a reading, you either have to represent that in
some way, which means that you need some sort of not a number representation,
or you have to make it impossible to read the sensor before checking that it
has a value. But the last is hard to achieve in C. (In C++ you can throw if the 
sensor doesn't have a value, so code that operates on the missing value will
never be executed).
> 
> > Now hasdata indicates that the return is not a number when it is false. This 
> > is better as it isn't informlly specified and much less likely to be misunderstood.
> I do agree that a boolean or other status indicator is often a better 
> choice, because you are less likely to get it wrong (even though it is 
> no more and no less "formally" or "informally" specified). 
> 
INT_MAX is a value. So if you say "in this context, it is not a value" then that's legitimate,
but it's an informal specification in a way that "this boolean indicates an error condition"
is not.
>
> Alternatively, the return value can be within a struct, and then the 
> access functions would make it very difficult to use incorrectly.
> > But all you are achieving is to move the NaN representation out of the return 
> > value and into a flag. You still have a not a number value, and there's still the 
> > risk that it will be used as a real value.
> There is no way to make a system so foolproof that no fool can get it 
> wrong. But the suggestions here so far make it a /lot/ harder to get 
> wrong than using floating point NaN's.
> 
As Kaz explained, NaNs propagate. The intention is that we can do a complex series
of calculations, which may either have an error in it or have a mathematically
undefined value. Then if the final result is NaN, we know that the error has ocurred.
Now of course if the original NaN was generated as the result of a programmng error,
you can only try to mitigate the error in some way. The real solution is to correct
the code. But that can't be done at runtime and, with the best will in the world,
errors will slip through.
If you say "0x80000000 means sensor fail", and pass that through to a long series
of calculations, you might get lucky and trigger a hardware overflowe trap. But
more likely the hardware wont; trap on overflow and you will get a number out.
And it might even be in the range of legitimate values.

That's why NaNs were invented. They are not designed as nuisance to derail 
programs. They're to indicate that a calculation has an error in it, and to enable
the program to detect that and take appropriate action. 
> 
> And I am not saying it is not unusable as a choice - I am just saying it 
> is a bad choice compared to many alternatives, and not one I would ever 
> consider in my work. It's easy to get /so/ much better. 
>
No, its not easy to improve on the IEEE's system of non-signalling NaNs.
 I am not saying the IEEE are gods and their system cannot be improved, 
at all, or that it should be used in all cases. But it's not easy to get better 
than "if there is no value, then the variable holds a NaN representation",
and then have a system so that all attempted operations on that value
also produce NaN, without any effort on the programmer's part. 
>
> (I have worked on safety-critical systems, where failure, in extreme 
> cases, could result in death. Most of my work is not that critical, 
> however.)
>
It may be that you don't use floating point at all in such systems. But that
wouldn't be because IEEE has a system of NaNs. It would be because it's
too hard to get exact limits for accuracy with floating point.

[toc] | [prev] | [next] | [standalone]


#175386

FromDavid Brown <david.brown@hesbynett.no>
Date2023-09-13 14:36 +0200
Message-ID<udsach$24go6$1@dont-email.me>
In reply to#175378
On 13/09/2023 13:45, Malcolm McLean wrote:
> On Wednesday, 13 September 2023 at 12:02:44 UTC+1, David Brown wrote:
>> On 13/09/2023 10:47, Malcolm McLean wrote:
>>> On Tuesday, 12 September 2023 at 19:07:54 UTC+1, Scott Lurndal wrote:
>>>> Malcolm McLean <malcolm.ar...@gmail.com> writes:
>>>>> On Tuesday, 12 September 2023 at 17:48:52 UTC+1, Scott Lurndal wrote:
>>>>>> Malcolm McLean <malcolm.ar...@gmail.com> writes:
>>>>>>> On Tuesday, 12 September 2023 at 16:17:18 UTC+1, Ben Bacarisse wrote:
>>>>>>>> Malcolm McLean <malcolm.ar...@gmail.com> writes:
>>>>>>>>
>>>>>>
>>>>>>>> I can (timeliness comes to mind) but that would be quibbling. The big
>>>>>>>> issue is that I reject the notion that one error implies one of two
>>>>>>>> behaviours.
>>>>>>>>
>>>>>>>> Why does this matter? Because it's just programming. There should be a
>>>>>>>> specification where you have left a void for this mystery program. The
>>>>>>>> life support system should be specified to provide timely and correct
>>>>>>>> results to the oxygen valve or to stop in such a way to provoke other
>>>>>>>> systems to trigger the alarms other wise.
>>>>>>>>
>>>>>>> It's specified to always control the flow of oxygen, based on various readings
>>>>>>> it takes from sensors attached to the patient.
>>>>>> Isn't that what Ben just wrote?
>>>>>>>>
>>>>>>>> Putting an abort() call and the end of sign(x) (if that is indeed what
>>>>>>>> you are suggesting) is called meeting the specification. Of course
>>>>>>>> there can be bugs (the call was missing at first) but that is just
>>>>>>>> programming. There are, of course, thousands of other fixes.
>>>>>>>>
>>>>>>> Not. it's not meeting the specification.
>>>>>>> The code might look like this.
>>>>>>
>>>>>>> double sensor_value = readsensors();
>>>>>> I sure hope not. There's no need to use floating point
>>>>>> in this case. The flow-rate is in units of O2 per unit time.
>>>>>>
>>>>>> e.g milliliters per millisecond.
>>>>>>
>>>>>> If you need higher resolution, microliters per microsecond.
>>>>>>
>>>>>> In both cases, they're simple integers well within the
>>>>>> range of a 32-bit unsigned integer and there will never
>>>>>> be a NaN.
>>>>>>
>>>>> So what happens if the sensor doesn't give a reading?
>>>> Whatever the design document for the O2 sensor requirements
>>>> specifies.
>>>>
>>> Most devices attached to microprocessors do put bits on the bus
>>> which represent fixed-point values. But this is a higher level function
>>> which is reading one or more sensors, and then combining the results
>>> into a single return value (you might have several sensors and it is
>>> taking an average). If the processor supports floating point, there's no
>>> particular reason not to use it, and to keep everything in the physical
>>> sensor's fixed point format which you read in at a low level.
>>>>
>>>> I would assume that the designer would anticipate such a
>>>> condition and the function that obtains the sensor reading
>>>> would indicate a failure condition that would be handled
>>>> according to the design specification. There is no need
>>>> to use a NaN for that, there are dozens of alternatives.
>>>>
>>> So an alternative would be
>>>
>>> /* return sensor reading in 16:16 fixed point format, INT_MAX for
>>> sensor fail */
>>> sint32_t readsensors();
>>>
>> typedef int32_t Q15_16_t;
>> static const Q15_16_t sensor_fail = (Q15_16_t) 0x80000000;
>>
>> Q15_16_t x = read_sensors();
>> if (x == sensor_fail) {
>> ...
>> } else {
>> ...
>> }
>>
>> "sint32_t" would be assumed to be an alias for "int32_t". If you mean a
>> fixed point format, the most common practice is the Q format.
>>> So what have we done? We got an informally specified NaN. INT_MAX
>>> is "not a number" in this context.
>> Yes, it is all explicit. It is not "informally" specified, unless
>> you've failed to make the specification clear. If it is there in the
>> code and documentation, it is "formally" specified.
>>
> Scott said "we have no NaNs". But what he meant was that we have no
> NaNs as formally specified by IEEE. 

I took Scott's "NaNs never occur in my code" comment to mean that NaN's 
- floating point NaNs, since that was the context - do not occur in the 
code he writes.  He wrote what he meant (AFAIK), and it was perfectly clear.

> We still have representations which
> indicate that a varibale doesn't hold a number. But because he hasn't called
> them "not a number representations" in a formal way, they are "informally
> specified".

The term "NaN" almost always refers to the values defined by IEEE for 
its floating point formats.  If that's not what you mean, say that.

This has /nothing/ to do with "formality".  Something is "formal" is it 
is well described and accurately specified and documented - otherwise it 
is "informal".  A function that documents a particular result to 
indicate an invalid reading is "formal", while a function that assumes 
it is obvious that invalid readings give a NaN would be "informal".

Discussions with you in this group are often very difficult, because you 
inhabit a Humpty-Dumpty world where you think words mean exactly what 
you intend them to mean - rather than what everyone else thinks they 
mean.  /Please/ learn to write in the same language the rest of us do, 
and /please/ make it clear when you are "Malcolm-NaN's", 
"Malcolm-formal", and any other private non-standard terms you want to use.


>   If the sensor doesn't return a reading, you either have to represent that in
> some way, which means that you need some sort of not a number representation,
> or you have to make it impossible to read the sensor before checking that it
> has a value. But the last is hard to achieve in C. (In C++ you can throw if the
> sensor doesn't have a value, so code that operates on the missing value will
> never be executed).

Both are simple to do in C.  Exceptions are nothing more than an 
alternative way to return particular types of values that are convenient 
and efficient for some kinds of coding.

>>
>>> Now hasdata indicates that the return is not a number when it is false. This
>>> is better as it isn't informlly specified and much less likely to be misunderstood.
>> I do agree that a boolean or other status indicator is often a better
>> choice, because you are less likely to get it wrong (even though it is
>> no more and no less "formally" or "informally" specified).
>>
> INT_MAX is a value. So if you say "in this context, it is not a value" then that's legitimate,
> but it's an informal specification in a way that "this boolean indicates an error condition"
> is not.

Nonsense.  Please learn what "formal" and "informal" mean.

INT_MAX is a valid value for an "int".  That does not mean it is a valid 
value for a sensor reading.

>>
>> Alternatively, the return value can be within a struct, and then the
>> access functions would make it very difficult to use incorrectly.
>>> But all you are achieving is to move the NaN representation out of the return
>>> value and into a flag. You still have a not a number value, and there's still the
>>> risk that it will be used as a real value.
>> There is no way to make a system so foolproof that no fool can get it
>> wrong. But the suggestions here so far make it a /lot/ harder to get
>> wrong than using floating point NaN's.
>>
> As Kaz explained, NaNs propagate. 

They do, in some circumstances.  And that can be a convenient thing, in 
some circumstances.  (That's why they exist as a concept.)

> The intention is that we can do a complex series
> of calculations, which may either have an error in it or have a mathematically
> undefined value. Then if the final result is NaN, we know that the error has ocurred.
> Now of course if the original NaN was generated as the result of a programmng error,
> you can only try to mitigate the error in some way. The real solution is to correct
> the code. But that can't be done at runtime and, with the best will in the world,
> errors will slip through.
> If you say "0x80000000 means sensor fail", and pass that through to a long series
> of calculations, you might get lucky and trigger a hardware overflowe trap. But
> more likely the hardware wont; trap on overflow and you will get a number out.
> And it might even be in the range of legitimate values.

If you write incorrect code that does not do what you intend it to do, 
it might fail - is that your revelation?

> 
> That's why NaNs were invented. 

They were developed to allow some kinds of calculations to be done more 
efficiently with a check at the end for an error summary, rather than in 
the middle.  And sometimes that's a good idea - but certainly not always.

> They are not designed as nuisance to derail
> programs. They're to indicate that a calculation has an error in it, and to enable
> the program to detect that and take appropriate action.
>>
>> And I am not saying it is not unusable as a choice - I am just saying it
>> is a bad choice compared to many alternatives, and not one I would ever
>> consider in my work. It's easy to get /so/ much better.
>>
> No, its not easy to improve on the IEEE's system of non-signalling NaNs.

Of course it is - for situations where floating point NaN's are not 
ideal.  Such as for safety-critical systems.

>   I am not saying the IEEE are gods and their system cannot be improved,
> at all, or that it should be used in all cases. But it's not easy to get better
> than "if there is no value, then the variable holds a NaN representation",
> and then have a system so that all attempted operations on that value
> also produce NaN, without any effort on the programmer's part.
>>
>> (I have worked on safety-critical systems, where failure, in extreme
>> cases, could result in death. Most of my work is not that critical,
>> however.)
>>
> It may be that you don't use floating point at all in such systems. 

Generally, you don't.

> But that
> wouldn't be because IEEE has a system of NaNs. It would be because it's
> too hard to get exact limits for accuracy with floating point.

It is not remotely difficult to control your accuracy and error limits 
with floating point.

Usually you don't use floating point in such systems because you aim to 
make them small and have minimal functionality (so that there is less 
that can go wrong, and less to check for correctness), and many small 
microcontrollers do not have floating point hardware.

But if it is easier to write code simply and correctly using floating 
point, then that's what you do.  And you make sure your calculations are 
valid, and you never, ever see a NaN.  Since you have full control and 
awareness of the validity at all times, and never have NaNs, it does not 
matter whether your floating point formats support them or not - they 
are irrelevant.

[toc] | [prev] | [next] | [standalone]


#175392

Fromscott@slp53.sl.home (Scott Lurndal)
Date2023-09-13 13:43 +0000
Message-ID<60jMM.5116$quJ8.2754@fx18.iad>
In reply to#175386
David Brown <david.brown@hesbynett.no> writes:
>On 13/09/2023 13:45, Malcolm McLean wrote:

>>> Yes, it is all explicit. It is not "informally" specified, unless
>>> you've failed to make the specification clear. If it is there in the
>>> code and documentation, it is "formally" specified.
>>>
>> Scott said "we have no NaNs". But what he meant was that we have no
>> NaNs as formally specified by IEEE. 
>
>I took Scott's "NaNs never occur in my code" comment to mean that NaN's 
>- floating point NaNs, since that was the context - do not occur in the 
>code he writes.  He wrote what he meant (AFAIK), and it was perfectly clear.

Indeed, NaN is a term of art referring specifically to the IEEE
floating point standard.   I've never seen "NaN" used in any
other context (albeit some use it to refer to their grandmother :-).

<snip>

>Both are simple to do in C.  Exceptions are nothing more than an 
>alternative way to return particular types of values that are convenient 
>and efficient for some kinds of coding.

Albeit an expensive and complex alternative way.   One generally avoided
in real-time code.

[toc] | [prev] | [next] | [standalone]


#175395

FromJames Kuyper <jameskuyper@alumni.caltech.edu>
Date2023-09-13 11:10 -0400
Message-ID<udsjcl$25tg7$1@dont-email.me>
In reply to#175392
On 9/13/23 09:43, Scott Lurndal wrote:
...
> Indeed, NaN is a term of art referring specifically to the IEEE
> floating point standard.   I've never seen "NaN" used in any
> other context (albeit some use it to refer to their grandmother :-).

Most general rules have at least one exception.

The wikipedia article on NaNs points out that there is a private
standard for something called posits, which are an alternative to IEEE
754. They have a similar concept NaR:="Not a Real", which differs from a
NaN mainly in that NaRs compare equal to each other. There is a
particular implementation of posits using C++ templates called
cppPosits, that provides non-standard support for posit NaNs that are
similar to IEEE NaNs.

[toc] | [prev] | [next] | [standalone]


#175405

FromKaz Kylheku <864-117-4973@kylheku.com>
Date2023-09-13 17:12 +0000
Message-ID<20230913100854.153@kylheku.com>
In reply to#175395
On 2023-09-13, James Kuyper <jameskuyper@alumni.caltech.edu> wrote:
> On 9/13/23 09:43, Scott Lurndal wrote:
> ...
>> Indeed, NaN is a term of art referring specifically to the IEEE
>> floating point standard.   I've never seen "NaN" used in any
>> other context (albeit some use it to refer to their grandmother :-).
>
> Most general rules have at least one exception.
>
> The wikipedia article on NaNs points out that there is a private
> standard for something called posits, which are an alternative to IEEE
> 754. They have a similar concept NaR:="Not a Real", which differs from a
> NaN mainly in that NaRs compare equal to each other.

Speaking of which, I would prefer that NaN values compare equal
to themselves; i.e. if two operands are NaNs of the same bit pattern,
they compare equal. It's a repugnancy that they do not.

https://en.wikipedia.org/wiki/Law_of_identity

-- 
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca
NOTE: If you use Google Groups, I don't see you, unless you're whitelisted.

[toc] | [prev] | [next] | [standalone]


#175408 — [meta] spam in thread

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2023-09-13 11:22 -0700
Subject[meta] spam in thread
Message-ID<a79640d9-9f08-4a7c-a16d-bf824c0ca3f5n@googlegroups.com>
In reply to#175405
The newsgroup is suffering from a severe spam problem.
For the first time in the current blizzard, spam has been 
injected into a legiitmate thread itself. Which will cause major 
problems for me in filtering.

[toc] | [prev] | [next] | [standalone]


#175412 — Re: [meta] spam in thread

FromKaz Kylheku <864-117-4973@kylheku.com>
Date2023-09-13 18:40 +0000
SubjectRe: [meta] spam in thread
Message-ID<20230913113339.280@kylheku.com>
In reply to#175408
On 2023-09-13, Malcolm McLean <malcolm.arthur.mclean@gmail.com> wrote:
> The newsgroup is suffering from a severe spam problem.
> For the first time in the current blizzard, spam has been 
> injected into a legiitmate thread itself. Which will cause major 
> problems for me in filtering.

The main reason you would be having problems filtering is that you're on
Google Groups, where not only does most of the spam originate, but where
you have next to no tools to deal with it.

I don't see a problem here. Everything coming from Google Groups is
killed, except for people on my whitelist, including yourself.

Two idiots from non-Google-group accounts recently started replying to
spam posts. They are turfed. I'm referring to <doctor@doctor.nl2k.ab.ca>
and <yeti@tilde.institute>. That's a minor problem.

Everything looks clean from slrn connected to Eternal September.
The only hint of spam is that the newsgroup might show, say, 31
unread posts, but when I select it, there are only 7.

-- 
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca
NOTE: If you use Google Groups, I don't see you, unless you're whitelisted.

[toc] | [prev] | [next] | [standalone]


#175413 — Re: [meta] spam in thread

FromMalcolm McLean <malcolm.arthur.mclean@gmail.com>
Date2023-09-13 11:48 -0700
SubjectRe: [meta] spam in thread
Message-ID<3cba66d2-c4a6-47a2-a2ce-9c31d8298027n@googlegroups.com>
In reply to#175412
On Wednesday, 13 September 2023 at 19:40:47 UTC+1, Kaz Kylheku wrote:
> On 2023-09-13, Malcolm McLean <malcolm.ar...@gmail.com> wrote: 
> > The newsgroup is suffering from a severe spam problem. 
> > For the first time in the current blizzard, spam has been 
> > injected into a legiitmate thread itself. Which will cause major 
> > problems for me in filtering.
> The main reason you would be having problems filtering is that you're on 
> Google Groups, where not only does most of the spam originate, but where 
> you have next to no tools to deal with it. 
> 
> I don't see a problem here. Everything coming from Google Groups is 
> killed, except for people on my whitelist, including yourself. 
> 
> Two idiots from non-Google-group accounts recently started replying to 
> spam posts. They are turfed. I'm referring to <doc...@doctor.nl2k.ab.ca> 
> and <ye...@tilde.institute>. That's a minor problem. 
> 
> Everything looks clean from slrn connected to Eternal September. 
> The only hint of spam is that the newsgroup might show, say, 31 
> unread posts, but when I select it, there are only 7.
> 
I might have to move to a newsreader. I did use one before Google groups
was invented.
But I've only room for one computer, and so it has to be the computer provided
by work. And I'm a bit reluctant to put lots of non-work software on it.

[toc] | [prev] | [next] | [standalone]


Page 5 of 7 — ← Prev page 1 2 3 4 [5] 6 7  Next page →

Back to top | Article view | comp.lang.c


csiph-web