Documentation Archive

Developer

Mac Automation Scripting Guide

On This Page

Manipulating Numbers

Working with and manipulating numbers is an important and regular occurrence in scripting. Basic mathematic operations—such as addition, subtraction, multiplication, and division—are language-level features, but some other commonly performed operations require custom scripting.

Converting a Number to a String

Scripts often need to convert numbers to string format to display information to the user or populate a document. In AppleScript, this conversion can be accomplished most of the time simply by using the coercion operator as, as shown in Listing 20-1.

APPLESCRIPT

Open in Script Editor

Listing 20-1AppleScript: Coercing a number to a string
  1. 12 as string
  2. --> Result: "12"

In JavaScript, the same conversion can be accomplished by calling the toString() method, as shown in Listing 20-2.

JAVASCRIPT

Open in Script Editor

Listing 20-2JavaScript: Coercing a number to a string
  1. num = 12
  2. num.toString()
  3. // Result: "12"

Converting a Long Number to a String

In AppleScript, long numeric values are displayed in scientific notation. For example, 1234000000 is displayed by a script as 1.234E+9. When this value is coerced to a string, it becomes: "1.234E+9". The handler in Listing 20-3 converts a number, regardless of length, to a string of numeric characters instead of a numeric string in scientific notation.

APPLESCRIPT

Open in Script Editor

Listing 20-3AppleScript: Handler that converts a number to a string, regardless of length
  1. on convertNumberToString(theNumber)
  2. set theNumberString to theNumber as string
  3. set theOffset to offset of "E" in theNumberString
  4. if theOffset = 0 then return theNumberString
  5. set thePrefix to text 1 thru (theOffset - 1) of theNumberString
  6. set theConvertedNumberPrefix to ""
  7. if thePrefix begins with "-" then
  8. set theConvertedNumberPrefix to "-"
  9. if thePrefix = "-" then
  10. set thePrefix to ""
  11. else
  12. set thePrefix to text 2 thru -1 of thePrefix
  13. end if
  14. end if
  15. set theDecimalAdjustment to (text (theOffset + 1) thru -1 of theNumberString) as number
  16. set isNegativeDecimalAdjustment to theDecimalAdjustment is less than 0
  17. if isNegativeDecimalAdjustment then
  18. set thePrefix to (reverse of (characters of thePrefix)) as string
  19. set theDecimalAdjustment to -theDecimalAdjustment
  20. end if
  21. set theDecimalOffset to offset of "." in thePrefix
  22. if theDecimalOffset = 0 then
  23. set theFirstPart to ""
  24. else
  25. set theFirstPart to text 1 thru (theDecimalOffset - 1) of thePrefix
  26. end if
  27. set theSecondPart to text (theDecimalOffset + 1) thru -1 of thePrefix
  28. set theConvertedNumber to theFirstPart
  29. set theRepeatCount to theDecimalAdjustment
  30. if (length of theSecondPart) is greater than theRepeatCount then set theRepeatCount to length of theSecondPart
  31. repeat with a from 1 to theRepeatCount
  32. try
  33. set theConvertedNumber to theConvertedNumber & character a of theSecondPart
  34. on error
  35. set theConvertedNumber to theConvertedNumber & "0"
  36. end try
  37. if a = theDecimalAdjustment and a is not equal to (length of theSecondPart) then set theConvertedNumber to theConvertedNumber & "."
  38. end repeat if theConvertedNumber ends with "." then set theConvertedNumber to theConvertedNumber & "0"
  39. if isNegativeDecimalAdjustment then set theConvertedNumber to (reverse of (characters of theConvertedNumber)) as string
  40. return theConvertedNumberPrefix & theConvertedNumber
  41. end convertNumberToString

Listing 20-3 shows how to call the handler in Listing 20-3.

APPLESCRIPT

Open in Script Editor

Listing 20-4AppleScript: Calling a handler to convert a long number to a string
  1. convertNumberToString(8.72124243234E+11)
  2. --> Result: "872124243234"

Adding a Descriptive Suffix to a Number

The handlers Listing 20-5 and Listing 20-6 convert a number to a string and appends a suffix of "st", "nd", "rd", or "th", resulting in strings such as "1st", "2nd", "3rd", and "4th".

APPLESCRIPT

Open in Script Editor

Listing 20-5AppleScript: Handler that adds a descriptive suffix to a number
  1. on addDescriptiveSuffixToNumber(theNumber)
  2. -- Determine the suffix to add, based on the last two digits
  3. set theLastDigit to theNumber mod 10
  4. set theLastTwoDigits to theNumber mod 100
  5. set theSuffix to "th"
  6. if {1, -1} contains theLastDigit and {11, -11} does not contain theLastTwoDigits then
  7. set theSuffix to "st"
  8. else if {2, -2} contains theLastDigit and {12, -12} does not contain theLastTwoDigits then
  9. set theSuffix to "nd"
  10. else if {3, -3} contains theLastDigit and {13, -13} does not contain theLastTwoDigits then
  11. set theSuffix to "rd"
  12. end if
  13. -- Return the number and suffix
  14. return (theNumber as string) & theSuffix
  15. end addDescriptiveSuffixToNumber

JAVASCRIPT

Open in Script Editor

Listing 20-6JavaScript: Function that adds a descriptive suffix to a number
  1. function addDescriptiveSuffixToNumber(num) {
  2. // Convert the number to absolute value
  3. var integer = Math.abs(num)
  4. // Determine the suffix to add, based on the last two digits
  5. var suffix = "th"
  6. var lastDigit = integer % 10
  7. var lastTwoDigits = integer % 100
  8. if (lastDigit === 1 && lastTwoDigits !== 11) {
  9. suffix = "st"
  10. }
  11. else if (lastDigit === 2 && lastTwoDigits !== 12) {
  12. suffix = "nd"
  13. }
  14. else if (lastDigit === 3 && lastTwoDigits !== 13) {
  15. suffix = "rd"
  16. }
  17. // Return the number and suffix
  18. return num.toString() + suffix
  19. }

Listing 20-7 and Listing 20-8 show how to test the handlers in Listing 20-5 and Listing 20-6 by looping through a range of positive and negative numbers.

APPLESCRIPT

Open in Script Editor

Listing 20-7AppleScript: Testing a handler that adds a descriptive suffix to a number
  1. set theTestResults to ""
  2. repeat with a from -10 to 10
  3. set theTestResults to theTestResults & addDescriptiveSuffixToNumber(a)
  4. if a is less than 10 then set theTestResults to theTestResults & ", "
  5. end repeat
  6. theTestResults
  7. --> Result: "-10th, -9th, -8th, -7th, -6th, -5th, -4th, -3rd, -2nd, -1st, 0, 1st, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th, 9th, 10th"

JAVASCRIPT

Open in Script Editor

Listing 20-8JavaScript: Testing a function that adds a descriptive suffix to a number
  1. var testResults = ""
  2. for (var i = -10; i <= 10; i++) {
  3. testResults += addDescriptiveSuffixToNumber(i)
  4. if (i < 10) {
  5. testResults += ", "
  6. }
  7. }
  8. testResults
  9. // Result: "-10th, -9th, -8th, -7th, -6th, -5th, -4th, -3rd, -2nd, -1st, 0th, 1st, 2nd, 3rd, 4th, 5th, 6th, 7th, 8th, 9th, 10th"

Listing 20-9 and Listing 20-10 show how to call the handlers in Listing 20-5 and Listing 20-6 to identify positions of items in a list.

APPLESCRIPT

Open in Script Editor

Listing 20-9AppleScript: Example script that calls a handler to identify the descriptive numeric position of items in a list
  1. set thePersonList to {"Sal", "Ben", "Chris", "David"}
  2. set theListLength to length of thePersonList
  3. repeat with a from 1 to theListLength
  4. set theSuffixedNumber to addDescriptiveSuffixToNumber(a)
  5. set thePerson to item a of thePersonList
  6. display dialog "The " & theSuffixedNumber & " person in list is " & thePerson & "."
  7. end repeat

JAVASCRIPT

Open in Script Editor

Listing 20-10JavaScript: Example script that calls a function to identify the descriptive numeric position of items in a list
  1. var app = Application.currentApplication()
  2. app.includeStandardAdditions = true
  3. var personList = ["Sal", "Ben", "Chris", "David"]
  4. var listLength = personList.length
  5. for (var i = 0; i < listLength; i++) {
  6. var suffixedNum = addDescriptiveSuffixToNumber(i + 1)
  7. var person = personList[i]
  8. app.displayDialog(`The ${suffixedNum} person in list is ${person}.`)
  9. }

Adding Leading Zeros to a Number

The handlers in Listing 20-11 and Listing 20-12 convert a number to a string and prepends it with leading zeros until it reaches a certain length. They accept two parameters—the number to add leading zeros to and the maximum number of leading zeros to add. For example, if the maximum number of leading zeros is set to 2, the results range from 001 to 999. If the maximum number of leading zeros is 3, the results range from 0001 to 9999, and so on.

APPLESCRIPT

Open in Script Editor

Listing 20-11AppleScript: Handler that adds leading zeros to a number
  1. on addLeadingZerosToNumber(theNumber, theMaxLeadingZeroCount)
  2. -- Determine if the number is negative
  3. set isNegative to theNumber is less than 0
  4. -- Determine when the maximum number of digits will be reached
  5. set theThreshold to (10 ^ theMaxLeadingZeroCount) as integer
  6. -- If the number is shorter than the maximum number of digits
  7. if theNumber is less than theThreshold then
  8. -- If the number is negative, convert it to positive
  9. if isNegative = true then set theNumber to -theNumber
  10. -- Add the zeros to the number
  11. set theLeadingZeros to ""
  12. set theDigitCount to length of ((theNumber div 1) as string)
  13. set theCharacterCount to (theMaxLeadingZeroCount + 1) - theDigitCount
  14. repeat theCharacterCount times
  15. set theLeadingZeros to (theLeadingZeros & "0") as string
  16. end repeat
  17. -- Make the number negative, if it was previously negative
  18. if isNegative = true then set theLeadingZeros to "-" & theLeadingZeros
  19. -- Return the prefixed number
  20. return (theLeadingZeros & (theNumber as text)) as string
  21. -- If the number is greater than or equal to the maximum number of digits
  22. else
  23. -- Return the original number
  24. return theNumber as text
  25. end if
  26. end addLeadingZerosToNumber

JAVASCRIPT

Open in Script Editor

Listing 20-12JavaScript: Function that adds leading zeros to a number
  1. function addLeadingZerosToNumber(num, maxLeadingZeroCount) {
  2. var leadingZeros = ""
  3. // Convert the number to absolute value
  4. var absNum = Math.abs(num)
  5. // Determine when the maximum number of digits will be reached
  6. var threshold = Math.pow(10, maxLeadingZeroCount)
  7. // If the number is shorter than the maximum number of digits
  8. if (absNum < threshold) {
  9. // Prepare a leading zeros string
  10. var digitCount = Math.trunc(absNum).toString().length
  11. var charCount = maxLeadingZeroCount + 1 - digitCount
  12. for (var i = 0 ; i < charCount; i++) {
  13. leadingZeros += "0"
  14. }
  15. }
  16. // Add the zeros to the number
  17. var result = `${leadingZeros}${absNum}`
  18. // Make the number negative, if it was previously negative
  19. if (num < 0) {
  20. result = `-${result}`
  21. }
  22. // Return the prefixed number
  23. return result
  24. }

Listing 20-13 and Listing 20-14 show how to call the handlers in Listing 20-11 and Listing 20-12.

APPLESCRIPT

Open in Script Editor

Listing 20-13AppleScript: Calling a handler to add leading zeros to a number
  1. addLeadingZerosToNumber(9, 3)
  2. --> Result: "0009"

JAVASCRIPT

Open in Script Editor

Listing 20-14JavaScript: Calling a function to add leading zeros to a number
  1. addLeadingZerosToNumber(9, 3)
  2. // Result: "0009"

Comma-Delimiting a Number

The handlers Listing 20-15 and Listing 20-16 comma-delimit a numeric value and converts it to a string.

APPLESCRIPT

Open in Script Editor

Listing 20-15AppleScript: Handler that comma-delimits a number
  1. on convertNumberToCommaDelimitedString(theNumber)
  2. -- Convert the number to a string
  3. set theNumber to convertNumberToString(theNumber)
  4. -- Determine the length of the number
  5. set theNumberLength to length of theNumber
  6. -- Reverse the number so a comma can be added every 3 digits
  7. set theNumber to (reverse of every character of theNumber) as string
  8. -- Loop through the number's digits, add commas, and put the numbers back in the correct order
  9. set theConvertedNumber to ""
  10. repeat with a from 1 to theNumberLength
  11. if a is theNumberLength or (a mod 3) is not 0 then
  12. set theConvertedNumber to (character a of theNumber & theConvertedNumber) as string
  13. else
  14. set theConvertedNumber to ("," & character a of theNumber & theConvertedNumber) as string
  15. end if
  16. end repeat
  17. -- Return the comma delimited number
  18. return theConvertedNumber
  19. end convertNumberToCommaDelimitedString

JAVASCRIPT

Open in Script Editor

Listing 20-16JavaScript: Function that comma-delimits a number
  1. function convertNumberToCommaDelimitedString(num) {
  2. // Convert the number to a string
  3. var numString = num.toString()
  4. if (numString.indexOf("e") != - 1) {
  5. numString = convertNumberToString(numString)
  6. }
  7. // Reverse the number so a comma can be added every 3 digits
  8. numString = numString.split("").reverse().join("")
  9. var numStringWithCommas = ""
  10. // Determine the length of the number
  11. var numStringLength = numString.length
  12. // Loop through the number's digits, add commas, and put the numbers back in the correct order
  13. for (var i = 0; i < numStringLength; i++) {
  14. var toPrepend = numString[i]
  15. if (i != numStringLength - 1 && ((i + 1) % 3) == 0) {
  16. toPrepend = "," + toPrepend
  17. }
  18. numStringWithCommas = toPrepend + numStringWithCommas
  19. }
  20. // Return the comma delimited number
  21. return numStringWithCommas
  22. }

Listing 20-17 and Listing 20-18 shows how to call the handlers in Listing 20-15 and Listing 20-16.

APPLESCRIPT

Open in Script Editor

Listing 20-17AppleScript: Calling a handler to comma-delimit a number
  1. convertNumberToCommaDelimitedString(872124243234)
  2. --> Result: "872,124,243,234"

JAVASCRIPT

Open in Script Editor

Listing 20-18JavaScript: Calling a function to comma-delimit a number
  1. convertNumberToCommaDelimitedString(872124243234)
  2. // Result: "872,124,243,234"

Determining if a Number is an Odd Number

The handlers in Listing 20-28 and Listing 20-29 determine whether a whole number is even or odd. A returned value of false indicates the passed number is even; a returned value of true indicates the passed number is odd.

APPLESCRIPT

Open in Script Editor

Listing 20-28AppleScript: Handler that determines whether a number is odd
  1. on isNumberOdd(theNumber)
  2. if theNumber mod 2 is not 0 then
  3. return true
  4. else
  5. return false
  6. end if
  7. end isNumberOdd

JAVASCRIPT

Open in Script Editor

Listing 20-29JavaScript: Method that determines whether a number is odd
  1. function isNumberOdd(num) {
  2. return num % 2 !== 0
  3. }

Listing 20-30 and Listing 20-31 show how to call the handlers in Listing 20-28 and Listing 20-29.

APPLESCRIPT

Open in Script Editor

Listing 20-30AppleScript: Calling a handler to determine whether a number is odd
  1. isNumberOdd(3)
  2. --> Result: true

JAVASCRIPT

Open in Script Editor

Listing 20-31JavaScript: Calling a method to determine whether a number is odd
  1. isNumberOdd(3)
  2. // Result: true

Listing 20-32 and Listing 20-33 show how to call the handlers in Listing 20-28 and Listing 20-29 by prompting the user to enter an even number.

APPLESCRIPT

Open in Script Editor

Listing 20-32AppleScript: Example script that calls a handler to determine whether a user-entered number is odd
  1. repeat
  2. display dialog "Enter an even integer:" default answer ""
  3. try
  4. if text returned of result is not "" then set theNumberProvided to text returned of result as integer
  5. if isNumberOdd(theNumberProvided) is false then exit repeat
  6. end try
  7. end repeat

JAVASCRIPT

Open in Script Editor

Listing 20-33JavaScript: Example script that calls a method to determine whether a user-entered number is odd
  1. var app = Application.currentApplication()
  2. app.includeStandardAdditions = true
  3. while (true) {
  4. var result = app.displayDialog("Enter an even integer:", {defaultAnswer: ""})
  5. var text = result.textReturned
  6. if (text !== "") {
  7. var num = Number(text)
  8. if (!isNumberOdd(num)) {
  9. break
  10. }
  11. }
  12. }

Rounding and Truncating a Number

The handlers in Listing 20-34 and Listing 20-35 round and truncate a numeric value, and convert it to a string. Provide a numeric value and indicate a number of decimal places.

APPLESCRIPT

Open in Script Editor

Listing 20-34AppleScript: Handler for rounding and truncating a number
  1. on roundAndTruncateNumber(theNumber, numberOfDecimalPlaces)
  2. if numberOfDecimalPlaces is 0 then
  3. set theNumber to theNumber + 0.5
  4. return convertNumberToString(theNumber div 1)
  5. end if
  6. set theRoundingValue to "5"
  7. repeat numberOfDecimalPlaces times
  8. set theRoundingValue to "0" & theRoundingValue
  9. end repeat
  10. set theRoundingValue to ("." & theRoundingValue) as number
  11. set theNumber to theNumber + theRoundingValue
  12. set theModValue to "1"
  13. repeat numberOfDecimalPlaces - 1 times
  14. set theModValue to "0" & theModValue
  15. end repeat
  16. set theModValue to ("." & theModValue) as number
  17. set theSecondPart to (theNumber mod 1) div theModValue
  18. if length of (theSecondPart as text) is less than numberOfDecimalPlaces then
  19. repeat numberOfDecimalPlaces - (the length of (theSecondPart as text)) times
  20. set theSecondPart to ("0" & theSecondPart) as string
  21. end repeat
  22. end if
  23. set theFirstPart to theNumber div 1
  24. set theFirstPart to convertNumberToString(theFirstPart)
  25. set theNumber to (theFirstPart & "." & theSecondPart)
  26. return theNumber
  27. end roundAndTruncateNumber

JAVASCRIPT

Open in Script Editor

Listing 20-35JavaScript: Function for rounding and truncating a number
  1. function roundAndTruncateNumber(num, numDecimalPlaces) {
  2. if (numDecimalPlaces === 0) {
  3. num = num + 0.5
  4. return convertNumberToString(num / 1)
  5. }
  6. var roundingValue = "5"
  7. for (var i = 0; i < numDecimalPlaces; i++) {
  8. roundingValue = "0" + roundingValue
  9. }
  10. roundingValue = Number("0." + roundingValue)
  11. num += roundingValue
  12. var modValue = "1"
  13. for (var i = 0; i < numDecimalPlaces - 1; i++) {
  14. modValue = "0" + modValue
  15. }
  16. modValue = Number("0." + modValue)
  17. var secondPart = Math.floor((num % 1) / modValue)
  18. var secondPartStringLength = secondPart.toString().length
  19. if (secondPartStringLength < numDecimalPlaces) {
  20. var count = numDecimalPlaces - secondPartStringLength
  21. for (var i = 0; i < count; i++) {
  22. secondPart = "0" + secondPart
  23. }
  24. }
  25. var firstPart = Math.floor(num)
  26. firstPart = convertNumberToString(firstPart)
  27. return `${firstPart}.${secondPart}`
  28. }

Listing 20-36 shows how to call the handler in Listing 20-34.

APPLESCRIPT

Open in Script Editor

Listing 20-36AppleScript: Calling a handler to round and truncate a number
  1. roundAndTruncateNumber(1.04575, 3)
  2. --> Result: "1.046"