Number names: Difference between revisions

→‎{{header|AppleScript}}: Added long-scale options.
No edit summary
(→‎{{header|AppleScript}}: Added long-scale options.)
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.
 
Vanilla AppleScript can be more flexible if you're prepared to write the code. The following script below, like the ASObjC one above, returns short-scale number names, (which are easier to code anyway) andbut includes "and"s by default. However anAn optional parameter <code>without ands</code> can be usedadded into the call if you'dthe prefer"and"s are not towanted. haveAnother them.optional Alternativelyparameter, changing the <code>truewith longScale</code>, ingets thea topBritish-English linelong-scale ofresult, thewhile handlera tothird, <code>falsewith milliards</code>, willgets ''omit''a "and"slong-scale byresult defaultwith and"milliard", calls"billiard", will''etc.'' havebetween tothe include"-illion"s <code>withinstead ands</code>of to get them"thousand".
 
Both scripts can display strange results with numbers that are at the extreme limits of their floating-point resolution.
 
<lang applescript>-- Parameters:
-- 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.
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.
-- Script object containing the word lists and a recursive subhandler.
if (usingMilliards) then set (usingLongScale) to false
-- Script object containing the word listsdata and a recursivetwo subhandlersubhandlers.
script o
property scale : 1000
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", "septillion"}
property illiardLandmarks : {"thousand", "million", "milliard", "billion", "billiard", "trillion", "trilliard", "quadrillion", ¬
"quadrilliard", "quintillion", "quintilliard", "sextillion", "sextilliard", "septillion", "septilliard"}
property collector : {} -- Words collected here.
-- RecursiveDeal subhandler forwith the integer part of the number.
on parseIntnameInteger(n, landmarkNolandmarkIndex)
-- Recursively work to the "front" of the integernumber, "three or six "digits" at a time depending on the scale.
if (n > 999scale) then parseIntnameInteger(n div 1000scale, landmarkNolandmarkIndex + 1)
-- Deal withName each "threedigit-digit"group value on the way back.
set hundredsTensAndUnitsgroupValue to n mod 1000scale
-- FirstlyIf thea hundreds,group ifvalue's any.over They'll999, onlyits betop singlethree digits represent thousands in a long-scale naming. Deal with them first.
if (hundredsTensAndUnitsgroupValue > 99999) then
set end of my collector to item nameGroup(hundredsTensAndUnitsgroupValue div 100)1000, offalse, unitsAndTeenslandmarkIndex)
set end of o'smy collector to "minusthousand"
-- 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
if ((hundredsTensAndUnitsgroupValue >is 0) and (landmarkNolandmarkIndex > 0)) then set end of my collector to item landmarkNolandmarkIndex of my landmarks
end if
-- 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 parseIntif
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"
end if
-- Then the tens and units together, according to whether they require single words, hyphenated words or none.
set tensAndUnits to ngroupValue mod 100
if (tensAndUnits > 0) then
-- Insert the word "and" if enabled and appropriate.
Line 579 ⟶ 604:
((collector ends with "hundred") ¬
or (collector ends with "thousand") ¬
or ((landmarkNonotThousands) and (landmarkIndex is 0) and (collector is not {})))) then ¬
set end of my collector to "and"
if (tensAndUnits < 20) then
Line 592 ⟶ 617:
end if
end if
end nameGroup
-- Insert the "landmark" word for this point in the number, if applicable.
if ((hundredsTensAndUnits > 0) and (landmarkNo > 0)) then set end of my collector to item landmarkNo of my landmarks
end parseInt
end script
--(* Main handler code. *)
-- Adjust for a negative if requirednecessary.
if (n < 0) then set {end of o's collector, n} to {"minus", -n}
set end of o's collector to "minus"
-- Deal with the setinteger npart toof -nthe number.
end if
-- Deal with the integer part of the number first. Special-case zero, but otherwise parse.
if (n div 1 is 0) then
set end of o's collector to "zero"
else
tellif o to parseInt(nusingLongScale) div 1, 0)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
-- Deal with any fractional part, working forwards from the decimal point. (Vulnerable to floating-point inaccuracy atwith extreme lengthsvalues.)
if (n mod 1 > 0.0) then
set end of o's collector to "point"
Line 635 ⟶ 663:
end numberToEnglish
 
numberToEnglish from -3.6028797018963E60287970189634E+1012
--> "minus thirty-three trillion six hundred and two billion twenty-eight hundred and seventy-nine million seven hundred and ninety-sevenone thousand andeight eighteenhundred point nineand ninety-six point three four"
numberToEnglish from -3.6028797018963E60287970189634E+1012 without ands
--> "minus thirty-three trillion six hundred two billion twenty-eight hundred seventy-nine million seven hundred ninety-sevenone thousand eighteeneight point ninehundred ninety-six point three four"</lang>
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}}==
557

edits