Negative Numbers and NumberFormat

Mark Waddingham mark at livecode.com
Wed Apr 5 13:21:28 EDT 2017


On 2017-04-03 19:11, Bob Sneidar via use-livecode wrote:
> Was anyone aware that the sign takes up one of the digital in number
> format? For instance,
> 
> set the numberformat to "00";put -1 +0 & ":" & 0 +0 & ":" & 0 +0
> returns:
> -1:00:00
> 
> but
> set the numberformat to "00";put -12 +0 & ":" & 0 +0 & ":" & 0 +0
> returns:
> -12:00:00
> 
> Does no one else find that odd??

It looks odd, but is explainable. It has nothing to do with '-' eating 
up
places for 0 in the numberFormat, but to do with the type of things in
that expression:

Contrast:

set the numberformat to "00";put 0+0 & ":" & 0+0 & ":" & 0+0
   => 00:00:00

And:

set the numberformat to "00";put 0 & ":" & 0 & ":" & 0
   => 0:0:0

The reason here is that the token 0 in a script is actually treated as a 
string *until*
you do something to it which turns it into a number. Only numbers are 
subject to
numberFormat.

So, in the first case you are doing:

   put NUMBER & ":" & NUMBER & ":" & NUMBER

In the second case you are doing:

   put STRING & ":" & STRING & ":" & STRING

The & operator requires two strings, so in the first case the NUMBERs 
are being
converted to strings (and thus subject to numberFormat) whereas in the 
second
case they are already STRINGs so no conversion takes place.

I class this as an anomaly.

The correction would be that any token in script which *looks* like a 
number should
act like a number in terms of string conversion rules (including the 
application of
numberFormat), even if it can't be represented exactly as a number.

This rule would mean that as long as you don't attempt to do arithmetic 
on something
which looks like a number, how it looks will be preserved.

The latter bit about 'not being able to do arithmetic' might sound odd 
but it is
a reflection of the finiteness of computers.

For example, the engine currently uses IEEE doubles for all its 
arithmetic. Whilst
such things can represent a very large number of numbers (2^60 different 
values or
near enough), the actual range a double can represent is substantially 
bigger (many
orders of magnitude bigger, in fact - something like -10^300 to 
+10^300). This results
in there being many many string representations which map to the same 
double (for example
0 can be written as 0, 0.0, 0.00, 0.000, ...).

Indeed, doubles only have about 15 digits of decimal precision, meaning 
that if your
actual number has more than 15 non-zero digits before or after a lot of 
0's then
you'll get an approximation to the actual number (well, you'll get a 
number which is
within DBL_EPSILON of the real number, anyway - this kind of stuff gets 
pernickety very
very quickly).

In actual fact, the above rule can be extended further - and perhaps 
expressed more
succinctly as:

   If a string is converted to a number, then the actual conversion 
should not
   occur until it is absolutely needed.

The point here is that formatting a (decimal) string representation of a 
number
via numberFormat does not actually require conversion to an actual 
number - it can
be done using the string representation alone - and doing it that way 
would mean
that numbers would be preserved to look exactly as they did unless you 
actual poke
them with arithmetic.

Of course, you might argue that 'whats the point of numbers if you don't 
do
arithmetic on them' - but it is often the case that our programs 
manipulate
numbers without doing anything to them, we just need to know that 'they 
are
numbers'.

A good example is the json importers/exporters which exist. They do
zero arithmetic - they merely import and export existing data. In that 
case it
is very important that the data is preserved *as is* otherwise you can't 
roundtrip
(i.e. import data, and immediately export without changing anything).

Warmest Regards,

Mark.

-- 
Mark Waddingham ~ mark at livecode.com ~ http://www.livecode.com/
LiveCode: Everyone can create apps





More information about the use-livecode mailing list