[ENH] floatGlobals-ls

Richard A. O'Keefe ok at cs.otago.ac.nz
Tue Sep 21 04:07:01 UTC 2004


lex at cc.gatech.edu wrote:
	Before doing so, though, please consider that Infinity, at the
	least, is a fundamental value and seems worth having right at
	ones fingers.  It almost as basic as 0 and 1 and -1.
	
Infinity may be a fundamental value, but Float infinity is not that value.
Remember, in an ANSI Smalltalk with more than one kind of Float, each kind
has a DIFFERENT Infinity.

	True.  This seems very unimportant, though.  NaN's all operate the same
	(don't they?)

No.  In fact there are two fairly dramatically different kinds which should
not be treated the same.  (Doesn't anyone actually _read_ the IEEE standard?)

	And even if you create a NaN with the same bit pattern as
	another, they will be neither #= nor #== to each other.

Note also that +0.0 and -0.0 _are_ equal according to IEEE rules, but
they are different bit patterns.  Which is why Float needs a
    #isSameBitsAs: anotherFloat
method.  If you pass Floats to foreign code, the bits in a NaN _can_
matter.  Amongst other things the foreign code may expect to get back
the same bit pattern it gave you in the first place.

	Anyway, this seems like a separate matter.

Not really.  If you want to tie up a global variable with a special value,
you had better be quite clear about which value it is.  Is your global NaN
going to be a qNaN or an sNaN?  Once you've decided that, what is its sign
going to be?  (And yes, IEEE-conformant code _can_ determine the sign of a
NaN without examining the bit pattern.)

	> I'm especially unhappy about this because ANSI Smalltalk mandates
	> *three* floating-point classes (FloatE, FloatD, and FloatQ) and
	> *each* of them would want its own three global variables, because
	> FloatE infinity (if ANSI had it) could not be the same object as
	> FloatD infinity.
	
	There's no problem here.  [Infinity] can refer to one of them, and the
	other classes will have to do something more specialized like [EFloat
	infinity]. 
	 
But then _one_ of the classes gets to write its Infinity as Infinity and
the others have to write (classname infinity).  That kind of inconsistency
is such a pain.  The whole mess with the global variables is more trouble
than it's worth.

	It is exactly the same as with 1.52.  [1.52] can only evaluate to one
	kind of float.  If there is more than one kind of float, the other
	1.52's will have to be printed something like [1.52d] or [1.52ieee96]. 

I guess that people not only don't read the IEEE 754 standard, they don't
read the ANSI Smalltalk standard either.  The output of finite floating
point numbers is clearly spelled out there.

	That doesn't mean we should give up on using [1.52] for the most common
	type.
	
Nor does the ANSI standard require you to do it.

	Also, I actually meant the Infinity global to be a placeholder for a
	good infinity object, and not necessarily for [Float infinity].

But you were talking about printing (Float infinity) as Infinity; if they
are _not_ the same kind of object, then this shouldn't be done, and there
is no point in introducing an Infinity global *at this stage*.

If you want to have a 'good infinity object', fine.
*WHEN* you have one, make *that* be the global Infinity,
make *it* print as Infinity, and leave the floating point versions
printing as (classname infinity).

If you introduce Infinity now, changing it to be a 'good infinity object'
in the future stands a really excellent chance of breaking working code.

	It just
	happens that we have no other contenders right now, so [Float infinity]
	is winning by default.  And as long as it is winning, we may as well use
	short printStrings when possible.

I'm sorry?  I can see that it's important for Float infinity to have
*a* printString that reads back reliably, and that the printString should
be clear to human readers, but why does it need to be short?  Surely only
frequent things need to be short.

	Especially if someone types "Infinity" to get this value, it is
	nice if "Infinity" is how the value prints back out.
	
But if there is no global Infinity variable, nobody *will* type Infinity
to get that value.  Here you are arguing that if there is such a variable
then it is convenient if there is such a variable.  Of course, adding
such a variable will have nasty effects on any class that has an Infinity
class variable, like, oh, Float...
	
	> This is of particular interest because it's clear that Squeak _does_
	> have two floating-point types.  There's "Float" and there's "element
	> of a FloatArray".  (Anyone else find it confusing that the elements
	> of FloatArrays are not really Floats?)  
	
	It's interesting but it seems well engineered to me.  ShortFloatArray
	might be a better name... or it might be worse, because it sounds like
	the array is short, not the floats.
	
Straw man.  Float32Array, ArrayOfShortFloat, anyone can make up better names
than that straw man.  I do not see how it can possibly be 'good engineering'
to have "Float" mean "32-bit float" in one name and "64-bit float" in another.

	So my current thoughts are to kill NegativeInfinity and NaN, just to please
	the puritans, to update the printString's appropriately, and to leave the
	global Infinity around.  But I'll wait a little while to see how the
	discussion goes.
	
Precisely *because* you want a real 'good infinity object' *later*
you should *not* add a global Infinity variable *now*.

No puritan here; my concernes are severly practical.
We do not need this global variable mess.



More information about the Squeak-dev mailing list