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