Re: 1.0000023E+5 to 100000.23 as text?
Re: 1.0000023E+5 to 100000.23 as text?
- Subject: Re: 1.0000023E+5 to 100000.23 as text?
- From: Nigel Garvey <email@hidden>
- Date: Mon, 11 Dec 2000 12:44:47 +0000
Jason Bourque wrote on Sun, 10 Dec 2000 19:43:29 -0500:
>
Hello,
>
>
How would you go about converting scientific notation into text.
>
>
i.e.
>
>
1.0000023E+5 to 100000.23
I posted this number-to-text handler recently as part of another script.
There are shorter, mathematical methods, but this is text based to avoid
certain floating-point problems. It correctly interprets any number
presented by AppleScript in scientific notation - and most others; but if
the input number is one of the problem ones (such as 8439.29 or 8439.39,
which AppleScript presents as 8439.290000000001 and 8439.389999999999
respectively), the output will be a string representation of the
inaccuracy. For a complete solution with unknown input, I'd recommend
using it in conjunction with something like my truncate-to-string handler
(also below) with an adequately large decimal-place setting of (say) 15.
on numToStr(n)
-- the decimal point character on this machine
set dpChr to the middle character of ((1 / 2) as string)
set zeroStr to "0" & dpChr & "000000000000000000000000000000"
set s to n as string
if s contains "E" then
if n < 0 then set s to text 2 thru -1 of s -- lose any minus sign for
now
set mtLen to (count word 1 of s) - 1 -- the mantissa length
set chrList to characters 1 thru mtLen of s -- the mantissa characters
set item 2 of chrList to "" -- zap the decimal point
-- the target decimal point position (2 + exponent)
set dpPos to 2 + (text (mtLen + 2) thru -1 of s)
if dpPos > 1 then -- positive exponent
if dpPos comes after mtLen then -- append zeros
set the end of chrList to text 3 thru (2 + dpPos - mtLen) of
zeroStr
else if dpPos comes before mtLen then
-- insert a decimal point (allowing for displacement from empty
item 2)
set item dpPos of chrList to (item dpPos of chrList) & dpChr
end if -- do nothing if dpPos = mtLen
else -- negative exponent
if the last item of chrList is "0" then set the last item of
chrList to ""
set the beginning of chrList to text 1 thru (3 - dpPos) of zeroStr
end if
if n < 0 then set the beginning of chrList to "-" -- restore any
minus sign
set s to chrList as string
else
if s ends with (text 2 thru 3 of zeroStr) then set s to text 1 thru
-3 of s
end if
return s
end numToStr
(* Truncate n to d decimal places, result as string,
with or without rounding and/or trailing zeros *)
on trncToStr of n at d given rounding:rounding, padding:padding
-- the decimal point character on this machine
set dpChr to the middle character of ((1 / 2) as string)
tell n * (10 ^ d)
if rounding then
it div 0.5 - it div 1 -- round off
else
it div 1 -- truncate
end if
end tell
set s to numToStr(result) -- convert to text *here*
-- insert the decimal point and deal with trailing zeros as required
if d > 0 then
set i to -1
if not padding then
repeat while character i of s is "0" and i is not -d
set i to i - 1
end repeat
end if
set s to text 1 thru -(d + 1) of s & dpChr & text -d thru i of s
else
if d < 0 then -- negative values of d work too!
if s is "0" then set d to d + 1
set s to s & text 1 thru -d of "000000000000000"
end if
-- Make integer results (d <= 0) look like reals if padding is set
if padding then set s to s & dpChr & "0"
end if
s
end trncToStr
trncToStr of 1.0000023E+5 at 15 with rounding without padding
--> "100000.23"
trncToStr of 8439.389999999999 at 15 with rounding without padding
--> "8439.39"
NG