A few things Nigel Garvey has helped me whip into shape. Nigel, and others who understand these these things far better than me, have posted some great stuff to MacScripter. Check it out for more of this kind of thing.
Turn a byte number into a readable string, meant for file sizes. Not terribly accurate for a sum of lots of small files, (due to block size issues, not a bug in this), but good for any single file, or small number of files.
USAGE: set fileSizeString to convertByteSize on 7561726
--> "7.21 MB"
Input: integer or integral real - a number of bytes. Accepts scientific notation, i.e 7.561726E+6.
Output: string - the byte size returned in bytes, KB, MB, or GB as appropriate.
Error: non-numeric values, non integral reals. Propagates any error without traps. No input class checks.
-- convertByteSize -- by Nigel Garvey & Richard Morton, 2002 --
-- Convert bytes to a readable string in bytes-K-MB-GB as required.
-- Pass the number in bytes. Returns string.
to convertByteSize on theRawSize
set oneK to 2 ^ 10
set oneMB to 2 ^ 20
set oneGB to 2 ^ 30
tell theRawSize to ¬
if it ≥ oneGB then
return ((it div oneGB) & "." & text 2 thru 3 of ((100 + ((it mod oneGB) div (oneK * 1.0E+4))) as string) & " GB") as string
else if it ≥ oneMB then
return ((it div oneMB) & "." & text 2 thru 3 of ((100 + ((it mod oneMB) div (oneK * 10))) as string) & " MB") as string
else if it ≥ oneK then
return (it div oneK & " KB") as string
return (it & " bytes") as string
Return a time string in hours, minutes & seconds, from a time in seconds using the supplied separator character. Supports days up to 99 and only includes them if the time is one day or more. This is an updated version from NG on 11 April 2003.
USAGE: set timeString to elapsedTime from 8.639999E+6 against ":"
secondTime integer or integral real - the time, in seconds, to convert.
sepChar string - the separator character for the returned time string.
Output: string - an hours:minutes:seconds OR days:hours:minutes:seconds value.
Error: non numeric or non integral values.
-- elapsedTime -- by Nigel Garvey & Richard Morton, 2002-2003 --
-- Pass an integral value (handles reals) - the time in seconds - and
-- a separator character. Returns string.
on elapsedTime from secondTime against sepChar
set hms to (1000000 + secondTime mod days div hours * 10000 + ¬
secondTime mod hours div minutes * 100 + ¬
secondTime mod minutes div 1) as string
set hms to text 2 thru 3 of hms & sepChar & ¬
text 4 thru 5 of hms & sepChar & ¬
text 6 thru 7 of hms
if secondTime < days then return hms
return text 2 thru 3 of ((100 + secondTime div days) as string) & sepChar & hms
Just a rewrite of an example I saw in C. A classic recursive algorithm. Don't think about it too hard...
on factorial from n
if n = 0 then return 1
return n * (factorial from (n - 1))
Round & truncate a number to the specified number of places. This is an adaption of one of NG's handlers and was taken from 'aRounderRound', an excellent set of rouding handlers that is, I believe, available on MacScripter. A nice example of Nigel's innovative tell techniques. Susceptible to AS's floating point bugs, but works for numbers up to 536870911 - see below.
USAGE: set roundedNum to roundTrunc from 6.78905432 for 4
n real - the number to round & truncate
decPlaces integer - the number of decimal places to round to.
Output: real - the rounded & truncated number. Always rounds 5 upwards.
Error: non-numeric values
-- roundTrunc -- by Nigel Garvey & Richard Morton, 2001 --
-- Round and truncate a real to the required number of decimal places.
-- Pass a real & the number of decimal places to return (integer).
-- Returns real. 0.5 rounds up.
on roundTrunc from n for decPlaces
tell 10 ^ decPlaces
tell n * it to it div 0.5 - it div 1
return result / it
NG sent me this to fix a bug in TaxCalc. Many versions of AS have floating point problems with certain numbers and this works around the known ones. This is as written and includes Nigel's comments, which may help in understanding what he's done. Very clever.
-- roundCurrency -- by Nigel Garvey, 18Jun2002
-- Round and truncate a real to 2 decimal places.
to roundCurrency from n
-- Multiply by (root-10 squared) times 10 (not by 100) and round off
tell n * ((10 ^ 0.5) ^ 2) * 10 to get (it div 0.5 - it div 1)
-- Combine the string coercion with some mathematical reduction
-- to reduce the likelihood of exponential formatting (which happens if
-- the whole-number part of the result exceeds 536870911 (AS 1.3.7))
return (((result div 100) as string) & "." & text 2 thru 3 of ((result mod 100 + 100) as string))
The FooDoo Lounge is Copyright © Richard Morton 2002-2005
|| url: http://www.foodoo.sunreal.com.au/code/numerics.html
|| created: 27-May-04, 11:48 AM; updated: 27-May-04, 11:47 AM
|| size: 40123 bytes