Number names: Difference between revisions
Content added Content deleted
No edit summary |
(→{{header|AppleScript}}: Added long-scale options.) |
||
Line 544: | Line 544: | ||
NSNumberFormatter supports several natural languages and by default uses the one set for the user on the host machine. However, its English is limited to US English, so there are no "and"s in the results. |
NSNumberFormatter supports several natural languages and by default uses the one set for the user on the host machine. However, its English is limited to US English, so there are no "and"s in the results. |
||
Vanilla AppleScript can be more flexible if you're prepared to write the code. The |
Vanilla AppleScript can be more flexible if you're prepared to write the code. The script below, like the ASObjC one above, returns short-scale number names, but includes "and"s by default. An optional parameter <code>without ands</code> can be added to the call if the "and"s are not wanted. Another optional parameter, <code>with longScale</code>, gets a British-English long-scale result, while a third, <code>with milliards</code>, gets a long-scale result with "milliard", "billiard", ''etc.'' between the "-illion"s instead of "thousand". |
||
Both scripts can display strange results with numbers |
Both scripts can display strange results with numbers at the extreme limits of floating-point resolution. |
||
<lang applescript>-- Parameters: |
<lang applescript>-- Parameters: |
||
-- n: AppleScript integer or real. |
-- n: AppleScript integer or real. |
||
-- longScale (optional): boolean. Whether to use long-scale -illions instead of short-scale. Default: false |
|||
-- milliards (optional): boolean. Whether to use long-scale -illiards instead of long-scale thousands. |
|||
-- ands (optional): boolean. Whether to include "and"s in the result. Default: true. |
-- ands (optional): boolean. Whether to include "and"s in the result. Default: true. |
||
on numberToEnglish from n given ands:usingAnd : true |
on numberToEnglish from n given longScale:usingLongScale : false, milliards:usingMilliards : false, ands:usingAnd : true |
||
-- If 'with milliards' is specified, make sure the differently coded 'with longScale' is disabled. |
|||
⚫ | |||
if (usingMilliards) then set (usingLongScale) to false |
|||
⚫ | |||
script o |
script o |
||
property scale : 1000 |
|||
property unitsAndTeens : {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", ¬ |
property unitsAndTeens : {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", ¬ |
||
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"} |
"eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"} |
||
property tens : {missing value, "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"} |
property tens : {missing value, "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"} |
||
property landmarks : {"thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion"} |
property landmarks : {"thousand", "million", "billion", "trillion", "quadrillion", "quintillion", "sextillion", "septillion"} |
||
property illiardLandmarks : {"thousand", "million", "milliard", "billion", "billiard", "trillion", "trilliard", "quadrillion", ¬ |
|||
"quadrilliard", "quintillion", "quintilliard", "sextillion", "sextilliard", "septillion", "septilliard"} |
|||
property collector : {} -- Words collected here. |
property collector : {} -- Words collected here. |
||
-- |
-- Deal with the integer part of the number. |
||
on |
on nameInteger(n, landmarkIndex) |
||
-- Recursively work to the "front" of the |
-- Recursively work to the "front" of the number, three or six "digits" at a time depending on the scale. |
||
if (n |
if (n ≥ scale) then nameInteger(n div scale, landmarkIndex + 1) |
||
-- |
-- Name each digit-group value on the way back. |
||
set |
set groupValue to n mod scale |
||
-- |
-- If a group value's over 999, its top three digits represent thousands in a long-scale naming. Deal with them first. |
||
if ( |
if (groupValue > 999) then |
||
nameGroup(groupValue div 1000, false, landmarkIndex) |
|||
⚫ | |||
-- In this context, if the group's bottom three digits amount to zero, the appropriate "-illion", if any, must be added here. |
|||
set groupValue to groupValue mod 1000 |
|||
⚫ | |||
⚫ | |||
-- Deal with either a short-scale digit group or the bottom three digits of a long-scale one. |
|||
if (groupValue > 0) then |
|||
nameGroup(groupValue, true, landmarkIndex) |
|||
if (landmarkIndex > 0) then set end of my collector to item landmarkIndex of my landmarks |
|||
⚫ | |||
end nameInteger |
|||
-- Deal with a value representing a group of up to three digits. |
|||
on nameGroup(groupValue, notThousands, landmarkIndex) |
|||
-- Firstly the hundreds, if any. |
|||
if (groupValue > 99) then |
|||
set end of my collector to item (groupValue div 100) of unitsAndTeens |
|||
set end of my collector to "hundred" |
set end of my collector to "hundred" |
||
end if |
end if |
||
-- Then the tens and units together, according to whether they require single words, hyphenated words or none. |
-- Then the tens and units together, according to whether they require single words, hyphenated words or none. |
||
set tensAndUnits to |
set tensAndUnits to groupValue mod 100 |
||
if (tensAndUnits > 0) then |
if (tensAndUnits > 0) then |
||
-- Insert the word "and" if enabled and appropriate. |
-- Insert the word "and" if enabled and appropriate. |
||
Line 579: | Line 604: | ||
((collector ends with "hundred") ¬ |
((collector ends with "hundred") ¬ |
||
or (collector ends with "thousand") ¬ |
or (collector ends with "thousand") ¬ |
||
or (( |
or ((notThousands) and (landmarkIndex is 0) and (collector is not {})))) then ¬ |
||
set end of my collector to "and" |
set end of my collector to "and" |
||
if (tensAndUnits < 20) then |
if (tensAndUnits < 20) then |
||
Line 592: | Line 617: | ||
end if |
end if |
||
end if |
end if |
||
end nameGroup |
|||
-- Insert the "landmark" word for this point in the number, if applicable. |
|||
⚫ | |||
⚫ | |||
end script |
end script |
||
(* Main handler code. *) |
|||
-- Adjust for a negative if |
-- Adjust for a negative if necessary. |
||
if (n < 0) then |
if (n < 0) then set {end of o's collector, n} to {"minus", -n} |
||
⚫ | |||
-- Deal with the integer part of the number. |
|||
⚫ | |||
-- Deal with the integer part of the number first. Special-case zero, but otherwise parse. |
|||
if (n div 1 is 0) then |
if (n div 1 is 0) then |
||
set end of o's collector to "zero" |
set end of o's collector to "zero" |
||
else |
else |
||
if (usingLongScale) then |
|||
set o's scale to 1000000 |
|||
set o's landmarks to rest of o's landmarks |
|||
else if (usingMilliards) then |
|||
set o's landmarks to o's illiardLandmarks |
|||
end if |
|||
tell o to nameInteger(n div 1, 0) |
|||
end if |
end if |
||
-- Deal with any fractional part |
-- Deal with any fractional part. (Vulnerable to floating-point inaccuracy with extreme values.) |
||
if (n mod 1 > 0.0) then |
if (n mod 1 > 0.0) then |
||
set end of o's collector to "point" |
set end of o's collector to "point" |
||
Line 635: | Line 663: | ||
end numberToEnglish |
end numberToEnglish |
||
numberToEnglish from -3. |
numberToEnglish from -3.60287970189634E+12 |
||
--> "minus |
--> "minus three trillion six hundred and two billion eight hundred and seventy-nine million seven hundred and one thousand eight hundred and ninety-six point three four" |
||
numberToEnglish from -3. |
numberToEnglish from -3.60287970189634E+12 without ands |
||
--> "minus |
--> "minus three trillion six hundred two billion eight hundred seventy-nine million seven hundred one thousand eight hundred ninety-six point three four" |
||
numberToEnglish from -3.60287970189634E+12 with longScale |
|||
--> "minus three billion six hundred and two thousand eight hundred and seventy-nine million seven hundred and one thousand eight hundred and ninety-six point three four" |
|||
numberToEnglish from -3.60287970189634E+12 with milliards |
|||
--> "minus three billion six hundred and two milliard eight hundred and seventy-nine million seven hundred and one thousand eight hundred and ninety-six point three four"</lang> |
|||
=={{header|Applesoft BASIC}}== |
=={{header|Applesoft BASIC}}== |