# Negative Numbers and NumberFormat

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

```