Re: [boost] Stream input and output of NaN and infinity

Martin Bonner wrote:
-----Original Message----- Robert Ramey wrote:
Peter Dimov wrote:
It depends. Where do you draw the line? Is inf a number? Is -0.0 a number? You have to have NaN if you want to be able to represent x/y as a float.
That's the problem. x/y is not a valid operation if y is equal to 0. So it can't be represented as a number.
The fact that C++ permits such an operation makes C++ different than arithmetic. "different than SOME arithmetics". The arithmentic C++ (well, actually IEEE) defines is a perfectly sensible arithmetic.
The fact that C++ uses operators like "/" and defines them similar to - but not identical to - the way they are defined by standard arithmetic
Granted. It isn't the standard arithmetic.
is the source of all these problems. What problems? (Apart from the extra work involved for authors of libraries like serialization I mean!)
suppose that z = x * y generates a Nan or +Inf or whatever one some machine for some x and y. Now z contains an undefined value which is used on some other operations which presumably result in other types of Nan's. This behavior has the following problems:
a) it's undefined But MANY implementations define the behaviour, and define it in a way
----Original Message---- From: boost-bounces@lists.boost.org [mailto:boost-bounces@lists.boost.org] On Behalf Of Robert Ramey Sent: 16 May 2006 03:43 To: boost@lists.boost.org Subject: Re: [boost] Stream input and output of NaN and infinity that is useful.
b) it varies from machine to machine. On some machines the hardware will trap an abort the program as it won't throw a C++ exception. Other machines will store some variety of Nan in the result
Right. So if you need a maximally portable program you can't use NaN or +/-Inf. But many people /don't/ need a maximally portable program.
c) if it doesn't trap we're just massaging undefined values. d) we're getting some useless result but don't know it untill maybe later or many never.
How can any "real program" find this useful? How can such a program not be "broken". I suppose there might be some case where its OK but they would have to be special in some way.
I think what is special is that the authors would need to understand the issues. I used to work in transport modelling. We used to model different types of things (people, coal, food) travelling by different transport modes (bus, truck, boat) between different places. It makes perfect sense to talk about the cost of moving a ton of (eg) food between two places by boat being +infinity (it implies there is no boat route between the two places). It doesn't hurt the algorithm, because it will later assign the amount of food to be transported in proportion to exp(-cost) ... and hence it won't try and transport any food by boat. It might also makes sense to talk about the cost of moving a ton of coal between two places be NaN if there is no coal to move.
I say that C++ should be changed to so that the floats and operators which apply to them should implement what people expect from arithmetic operators.
Yes, but realistically that is never going to happen.
LOL - it seems you're right there. But that is not my point here.
Wouldn't it be better to support the use-cases that people have in real code?
well that's what we have to do. But it raises the issue of whether its worth spending time to support programs that are most likely broken in any case.
You could EASILY extend that argument to say that you shouldn't support floating point. I would suggest that in the set of float-point programs that want to use serialization the proportion of non-broken programs will be HIGHER in the sub-set that want support for +/-Inf and NaN than in the sub-set that don't want that support. -- Martin Bonner Martin.Bonner@Pitechnology.com Pi Technology, Milton Hall, Ely Road, Milton, Cambridge, CB4 6WZ, ENGLAND Tel: +44 (0)1223 203894

Martin Bonner wrote:
Robert Ramey wrote:
How can any "real program" find this useful? How can such a program not be "broken". I suppose there might be some case where its OK but they would have to be special in some way.
I think what is special is that the authors would need to understand the issues.
I used to work in transport modelling. We used to model different types of things (people, coal, food) travelling by different transport modes (bus, truck, boat) between different places.
It makes perfect sense to talk about the cost of moving a ton of (eg) food between two places by boat being +infinity (it implies there is no boat route between the two places). It doesn't hurt the algorithm, because it will later assign the amount of food to be transported in proportion to exp(-cost) ... and hence it won't try and transport any food by boat.
Ahhh - at last a short, concrete, believable scenario. so now we're evalating exp(-cost) where cost might be +Inf. How do you know what the exp function does in such a case? Is it defined? documented? etc. I can't see how the result of such a program can be trusted - even if one is not concerned about portability. How does one check such a result? Is it just assumed to be right if it looks reasonable? I don't know.
It might also makes sense to talk about the cost of moving a ton of coal between two places be NaN if there is no coal to move.
so our algorithm calculates the cost 0 tons of coal of moving from point a to point b (for which there is no route) with the expression exp(-Inf) * Nan and compares it to other floating point numbers and branches accordingly. It is the core of my concern that the current system permits and encourages programs like this to be written. Of course they might work in some instances but I don't think that's a good argument for doing things this way.
Wouldn't it be better to support the use-cases that people have in real code?
well that's what we have to do. But it raises the issue of whether its worth spending time to support programs that are most likely broken in any case.
You could EASILY extend that argument to say that you shouldn't support floating point.
I don't see how I could do that.
I would suggest that in the set of float-point programs that want to use serialization the proportion of non-broken programs will be HIGHER in the sub-set that want support for +/-Inf and NaN than in the sub-set that don't want that support.
That's where we disagree. Robert Ramey

Robert Ramey writes:
Martin Bonner wrote:
Robert Ramey wrote:
How can any "real program" find this useful? How can such a program not be "broken". I suppose there might be some case where its OK but they would have to be special in some way.
I think what is special is that the authors would need to understand the issues. [...] It makes perfect sense to talk about the cost of moving a ton of (eg) food between two places by boat being +infinity (it implies there is no boat route between the two places). It doesn't hurt the algorithm, because it will later assign the amount of food to be transported in proportion to exp(-cost) ... and hence it won't try and transport any food by boat.
Ahhh - at last a short, concrete, believable scenario.
so now we're evalating exp(-cost) where cost might be +Inf. How do you know what the exp function does in such a case? Is it defined? documented? etc. I can't see how the result of such a program can be trusted - even if one is not concerned about portability. How does one check such a result? Is it just assumed to be right if it looks reasonable? I don't know. [...]
OK, maybe you don't ever need to evaluate exp(-cost). You still might like to know that the result of a previous operation produced an Inf. Consider a program P that is part of a data processing chain. An upstream component gets bad data, or does something bad, and produces an Inf or NaN. P might need to pass that on to downstream processors, or detect it and take appropriate action. Or, consider an algorithm that might, occasionally, produce a legitimate Inf. How do I detect this case? Do I check errorno? No, that's error prone. Do I catch an exception? Only if the code that generates the Inf throws one, and that might not be an option (think threaded embedded systems where exceptions are banned). Probably, my only good option is to check for Inf and do something appropriate. If I need to pass the error-handling buck to a downstream process, emitting an Inf is a perfectly acceptable thing to do.
It is the core of my concern that the current system permits and encourages programs like this to be written. Of course they might work in some instances but I don't think that's a good argument for doing things this way.
There are plenty of use cases in which a NaN or Inf, either passed in from another process, or generated internally, is an expected and perfectly normal and understandable thing to get.
Wouldn't it be better to support the use-cases that people have in real code?
well that's what we have to do. But it raises the issue of whether its worth spending time to support programs that are most likely broken in any case.
Use case given above; the programs aren't broken, although they may be, and frequently are, part of a processing chai that involves _other_ programs that are broken. :-) My $0.2. :-) ---------------------------------------------------------------------- Dave Steffen, Ph.D. Fools ignore complexity. Software Engineer IV Pragmatists suffer it. Numerica Corporation Some can avoid it. ph (970) 419-8343 x27 Geniuses remove it. fax (970) 223-6797 -- Alan Perlis dgsteffen at numerica dot us
participants (3)
-
Dave Steffen
-
Martin Bonner
-
Robert Ramey