Negative Numbers and NumberFormat

Richard Gaskin ambassador at fourthworld.com
Thu Apr 6 11:35:56 EDT 2017


Paul Dupuis wrote:

 > On 4/5/17 5:48 PM, Richard Gaskin via use-livecode wrote:
 >>
 >> Confirmed - running this script in v9dp6 and again all the way back
 >> in v6.0:
 >>
 >> on mouseUp
 >>    set the numberformat to "###.###"
 >>    put 2.5 + 2.5 into x
 >>    set the numberformat to "000.000"
 >>    put 2.5 + 2.5 into y
 >>    put x &cr& y
 >> end mouseUp
 >>
 >> ...I get:
 >>
 >> 005.000
 >> 005.000
 >
 > NumberFormat on applies when the number is output or forced to convert
 > to a string (for example when doing string concatenation). The variant
 > script below:
 >
 > on mouseUp
 >    set the numberformat to "###.###"
 >    put 2.5 + 2.5 into x
 >    put x & cr after msg
 >    set the numberformat to "000.000"
 >    put 2.5 + 2.5 into y
 >    put y &cr after msg
 > end mouseUp
 >
 > results in:
 >
 > 005
 > 005.000

D'oh!  Yes, of course, I'd forgotten to make sure the value is coerced 
to a string for each unique output. Good catch.

It still seems off though, on the left side of the decimal. I would have 
expected the first value to be "5", given that "#" provides a space only 
when needed.

The LC Dict only discusses the distinction between "#" and "0" for 
numbers on the right side of the decimal, so I turned to "HyperTalk 2.2: 
The Book" for further guidance - and found what appear to be 
contradicting examples.

Among the many examples listed on p.411 for the "numberFormat" property are:

  set the numberFormat to "#.000"     - 0.25031 is displayed as .250
  set the numberFormat to "#.###"     - 0.25031 is displayed as .25
  set the numberFormat to "#.0000000" - 0.25031 is displayed as 0.2503100
  set the numberFormat to "#.000####" - 0.25031 is displayed as 0.25031

In each of those examples, what's happening on the right side of the 
decimal follows predictable rules.  But the left side seems 
inconsistent, in some cases using the "#" to force a leading 0 and in 
other cases not.

The relevant portion of the book's text for that entry says:

    The number of zeroes before the decimal point is the minimum number
    of integer digits to display.  HyperTalk always includes at least
    enough digits to specify the result of the calculation.  If there
    are more digits in the number than the numberFormat calls for,
    HyperTalk displays all the digits.  If there are fewer digits than
    the numberFormat calls for, HyperTalk adds leading zeroes to the
    beginning of the number.

There's further discussion of what happens after the decimal, but for 
what happens before the decimal only "0" is discussed, with no mention 
of what "#" should do when on the left side of the decimal.

The same omission is found (or more specifically, not found <g>) in the 
SuperTalk 3.0 Language Guide.

Unable to find clarity on that, I decided to try each of those HyperTalk 
examples above in LC - here's what I got:

  set the numberFormat to "#.000"     - 0.25031 is displayed as 0.250
  set the numberFormat to "#.###"     - 0.25031 is displayed as 0.25
  set the numberFormat to "#.0000000" - 0.25031 is displayed as 0.2503100
  set the numberFormat to "#.000####" - 0.25031 is displayed as 0.25031


Summary:

HyperTalk: I have no idea what it's doing.

LiveCode:  Either "#" or "0" to the left of the decimal will result
            in padding with leading 0s.

LC is certainly more consistent, but is it what we'd expect or want?

As Mark Waddingham noted, the engine code for numberFormat has been 
unchanged in such a long time that, regardless of what *might* be 
"best", it's unlikely to change at this point out of concern for scripts 
dependent on its current behavior.

Perhaps this raises a more interesting question:

Should we consider creating a new more fully-featured function which not 
only behaves as we might find ideal for decimal values, but also 
supports formatting of phone numbers, currency, and other common display 
formats?

Maybe a pair of functions would be useful so we could easily transform 
between display and calculation formats, something like:

put formattedValue(".25", "currency-US") -- returns: $0.25
put rawValue("$0.25". "currency-US")     -- returns: 0.25

Should there be some provision for doing that on a list where a column 
specifier could be supplied?:

put rawValue(tSomeLlist, "currency-US", 2) -- returns the list with
     values in column 2 converted to calculable formats.

This could be written in LC Script or LC Builder - might be a good 
community project....

--
  Richard Gaskin
  Fourth World Systems
  Software Design and Development for the Desktop, Mobile, and the Web
  ____________________________________________________________________
  Ambassador at FourthWorld.com                http://www.FourthWorld.com




More information about the use-livecode mailing list