• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Number to words [Re: Excel & AppleScripting]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Number to words [Re: Excel & AppleScripting]


  • Subject: Number to words [Re: Excel & AppleScripting]
  • From: "Nigel Garvey" <email@hidden>
  • Date: Wed, 10 Feb 2010 16:08:16 +0000

"Stockly, Ed" wrote on Mon, 8 Feb 2010 10:46:40 -0800:

>on NumberToWords(aNum)

That idea struck me as a pleasant way to waste an evening.  :)

  -- The 'lang' parameter should be some text ending with:
  -- "EN" (say) for short-scale -illions and the word "and" inserted in
the appropriate places.
  -- "US" for short-scale -illions and no "and"s.
  -- "GB" for the older British/French long-scale -illions and "and"s.
  on numberToEnglish(n, lang)
    script o
      property longScale : missing value -- Will be a boolean.
      property usingAnd : missing value -- Ditto.
      property unitsAndTeens : {"one", "two", "three", "four", "five",
"six", "seven", "eight", "nine", "ten", "eleven", "twelve", "thirteen",
"fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}
      property tens : {missing value, "twenty", "thirty", "forty",
"fifty", "sixty", "seventy", "eighty", "ninety"}
      property landmarks : {"thousand", "million", "billion",
"trillion", "quadrillion", "quintillion", "sextillion"}
      property longScaleLandmarks : {"thousand", "million", "thousand",
"billion", "thousand", "trillion", "thousand"}
      property collector : {} -- Words collected here.

      -- Recursive handler to deal with the non-fractional part of the number.
      on parseNumber(n, landmarkNo)
        -- Recurse to deal with the high end of the number first
        if (n > 999) then parseNumber(n div 1000, landmarkNo + 1)

        -- Deal with the "hundreds" digit from this group of three.
        set h to n mod 1000 div 100
        if (h > 0) then
          set end of o's collector to item h of unitsAndTeens
          set end of o's collector to "hundred"
        end if

        -- Deal with the tens and units.
        set tu to n mod 100
        if (tu > 0) then
          -- Insert "and" first, if required.
          if (usingAnd) and (o's collector is not {}) and ((end of o's
collector is in {"hundred", "thousand"}) or (landmarkNo is 0)) then set
end of o's collector to "and"

          if (tu < 20) then
            set end of o's collector to item tu of o's unitsAndTeens
          else
            set end of o's collector to item (tu div 10) of o's tens
            set u to tu mod 10
            if (u > 0) then set end of o's collector to item u of
unitsAndTeens
          end if
        end if

        -- Append any appropriate landmark (10 ^ 3) name.
        if (landmarkNo > 0) and (((not longScale) and (n mod 1000 > 0))
or ((longScale) and (n mod 1000000 > 0))) then set end of o's collector
to item landmarkNo of o's landmarks
      end parseNumber
    end script

    -- Main handler code. Set up.
    if (n is 0) then
      -- Special-case 0.
      set end of o's collector to "zero"
    else
      -- Adjust if negative.
      if (n < 0) then
        set end of o's collector to "minus"
        set n to -n
      end if

      -- Analyse language parameter.
      set o's longScale to (lang ends with "GB")
      if (result) then set o's landmarks to o's longScaleLandmarks
      set o's usingAnd to (lang does not end with "US")

      -- Deal with the non-fractional part of the number.
      o's parseNumber(n div 1, 0)

      -- Deal with any fractional part.
      -- (Vulnerable to floating-point errors.)
      if (n mod 1 > 0.0) then
        set end of o's collector to "point"
        set n to n * 10
        repeat
          set u to n mod 10 div 1
          if (u is 0) then
            set end of o's collector to "zero"
          else
            set end of o's collector to item (u div 1) of o's unitsAndTeens
          end if
          set n to n * 10
          if (n mod 10 is 0.0) then exit repeat
        end repeat
      end if
    end if

    -- Make the assembled words into a single text.
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to space
    set English to o's collector as text
    set AppleScript's text item delimiters to astid

    return English
  end numberToEnglish

  numberToEnglish(-1.23456789012345E+12, "EN")
  --> "minus one trillion two hundred and thirty four billion five
hundred and sixty seven million eight hundred and ninety thousand one
hundred and twenty three point four five"

  numberToEnglish(-1.23456789012345E+12, "US")
  --> "minus one trillion two hundred thirty four billion five hundred
sixty seven million eight hundred ninety thousand one hundred twenty
three point four five"

  numberToEnglish(-1.23456789012345E+12, "GB")
  --> "minus one billion two hundred and thirty four thousand five
hundred and sixty seven million eight hundred and ninety thousand one
hundred and twenty three point four five"


NG

 _______________________________________________
Do not post admin requests to the list. They will be ignored.
AppleScript-Users mailing list      (email@hidden)
Help/Unsubscribe/Update your Subscription:
Archives: http://lists.apple.com/archives/applescript-users

This email sent to email@hidden

  • Follow-Ups:
    • Re: Number to words [Re: Excel & AppleScripting]
      • From: Shane Stanley <email@hidden>
    • Re: Number to words [Re: Excel & AppleScripting]
      • From: "Stockly, Ed" <email@hidden>
  • Prev by Date: Re: Coercing an array of aliases to files
  • Next by Date: Re: Number to words [Re: Excel & AppleScripting]
  • Previous by thread: Re: Coercing an array of aliases to files
  • Next by thread: Re: Number to words [Re: Excel & AppleScripting]
  • Index(es):
    • Date
    • Thread