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: Tue, 12 Dec 2000 15:22:46 +0000
"Mike Miller" wrote on Mon, 11 Dec 2000 12:37:57 -0600:
>
Jason Bourque <email@hidden> asked:
>
>How would you go about converting scientific notation into text.
>
>
>
>i.e.
>
>
>
>1.0000023E+5 to 100000.23
>
>
Try the UnScientificNotate AppleScript snippet from the ESG Labs Snippets
>
page:
>
>
http://www.esglabs.com/snippets/
This works very well, but still fails with the problem numbers I
mentioned earlier - such as 8439.39, which comes out as
"8439.389999999999".
I've now cured the bug in my previous effort and have rethought the logic
so that the relevant bits from the two handlers are combined into one.
Like UnScientificNotate, it produces results that look like integers or
reals, as appropriate, but it can't handle *quite* such large numbers! It
also produces a decimal point character to match the Numbers setting on
the host machine.
on numToStr(n)
set d to 20 -- a hopefully adequate power (of 10) by which to multiply
-- the decimal point character on this machine
set dpChr to the middle character of ((1 / 2) as string)
set zeroStr to "00000000000000000000"
-- Multiple by 10 ^ d and round off to convert to a whole number
-- and (hopefully) to avoid problem numbers
n * (10 ^ d)
set s to (result div 0.5 - result div 1) as string
if n < 0 then set s to text 2 thru -1 of s -- lose any minus sign for
now
if s contains "E" then
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
-- Append (2 + exponent - mantissa length) trailing zeros
set z to 2 + (word -1 of s) - mtLen -- exponent always positive here
if the result > 0 then
repeat while z > (count zeroStr) -- get more zeros if required
set zeroStr to zeroStr & zeroStr
end repeat
set the end of chrList to text 1 thru z of zeroStr
end if
set s to chrList as string
end if
-- s is now "0" or (n * (10 ^ d)) as numeric string
-- Doctor it to represent the actual value of n
if the class of (n as number) is integer then
if n is not 0 then set s to text 1 thru -(d + 1) of s
else -- real
if n is 0 then set d to 1
set i to -1
repeat while character i of s is "0" and i > -d
set i to i - 1
end repeat
if n ^ 2 is greater than or equal to 1 then
set s to text 1 thru -(d + 1) of s & dpChr & text -d thru i of s
else -- n is between 0 and 1
set s to "0" & dpChr & text -d thru i of (zeroStr & s)
end if
end if
if n < 0 then set s to "-" & s -- restore "-" to negatives
return s
end numToStr
numToStr(1.0000023E+5)
--> "100000.23"
numToStr(8439.39) -- compiles as 8439.389999999999
--> "8439.39"
numToStr("1.23456789E+150")
-->
"12345678900000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000
00.0"
NG