Numerical and alphabetical suffixes: Difference between revisions

m
m (elided a stray solidus.)
m (→‎{{header|Wren}}: Minor tidy)
 
(40 intermediate revisions by 11 users not shown)
Line 1:
{{draft task}}
 
This task is about expressing numbers with an attached (abutted) suffix multiplier(s),   the suffix(es) could be:
::*   an alphabetic (named) multiplier which could be abbreviated
::*    metric  multiplier(s) which can be specified multiple times
::*   "binary" multipliesmultiplier(s) which can be specified multiple times
::* &nbsp; explanation marks (<big>'''!'''</big>) which indicate a factorial or multifactorial
 
Line 46:
'''GRoss''' multiply the number by '''144''' (twelve dozen)
'''GREATGRoss''' multiply the number by '''1,728''' (a dozen gross)
'''GOOGLEsGOOGOLs''' multiply the number by '''10^100''' (ten raised to the 100&sup>th</sup> power)
 
 
Line 96:
··· the number of factorial symbols that can be specified is to be unlimited &nbsp; (as per what can be entered/typed) ···
 
 
Note that these factorial products aren't &nbsp; ''super─factorials'' &nbsp; where (4!)! would be (24)!.
 
Factorial suffixes aren't, of course, the usual type of multipliers, but are used here in a similar vein.
Line 127 ⟶ 125:
 
;Related tasks:
:* &nbsp; [[Multifactorial]] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (which has a clearer and more succinct definition of multifactorials.)
:* &nbsp; [[Factorial]]
 
:* &nbsp; [[Abbreviations, simple]]
 
:* &nbsp; [[Abbreviations, easy]]
{{Template:Strings}}
:* &nbsp; [[Abbreviations, automatic]]
:* &nbsp; [[Commatizing numbers]]
:* &nbsp; [[Longest common prefix]]
<br><br>
 
=={{header|Factor}}==
===Functional===
<syntaxhighlight lang="factor">USING: combinators combinators.short-circuit formatting fry
grouping grouping.extras kernel literals math math.functions
math.parser math.ranges qw regexp sequences sequences.deep
sequences.extras sets splitting unicode ;
IN: rosetta-code.numerical-suffixes
 
CONSTANT: test-cases {
qw{ 2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre }
qw{ 1,567 +1.567k 0.1567e-2m }
qw{ 25.123kK 25.123m 2.5123e-00002G }
qw{ 25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei }
qw{ -.25123e-34Vikki 2e-77gooGols }
qw{
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!!
9!!!!!!!!!
}
}
 
CONSTANT: alpha {
{ "PAIRs" 2 } { "DOZens" 12 } { "SCOres" 20 }
{ "GRoss" 144 } { "GREATGRoss" 1,728 }
${ "GOOGOLs" 10 100 ^ }
}
 
CONSTANT: metric qw{ K M G T P E Z Y X W V U }
 
! Multifactorial
: m! ( n degree -- m ) neg 1 swap <range> product ;
 
! Separate a number from its suffix(es).
! e.g. "+1.567k" -> 1.567 "k"
: num/suffix ( str -- n suffix(es) )
dup <head-clumps> <reversed> { } like "" map-like
[ string>number ] map [ ] find [ tail* ] dip swap ;
 
! Checks whether str1 is an abbreviation of str2.
! e.g. "greatGRo" "GREATGRoss" -> t
: abbrev? ( str1 str2 -- ? )
{
[ [ >upper ] [ [ LETTER? ] take-while head? ] bi* ]
[ [ length ] bi@ <= ]
} 2&& ;
 
! Convert an alpha suffix to its multiplication function.
! e.g. "Doz" -> [ 12 * ]
: alpha>quot ( str -- quot )
[ alpha ] dip '[ first _ swap abbrev? ] find nip second
[ * ] curry ;
 
! Split a suffix composed of metric and binary suffixes into its
! constituent parts. e.g. "Vikki" -> { "Vi" "k" "ki" }
: split-compound ( str -- seq )
R/ (.i|.)/i all-matching-subseqs ;
 
! Convert a metric or binary suffix to its multiplication
! function. e.g. "k" -> [ 10 3 ^ * ]
: suffix>quot ( str -- quot )
dup [ [ 0 1 ] dip subseq >upper metric index 1 + ] dip
length 1 = [ 3 * '[ 10 _ ^ * ] ] [ 10 * '[ 2 _ ^ * ] ] if ;
 
! Apply suffix>quot to each member of a sequence.
! e.g. { "Vi" "k" "ki" } ->
! [ [ 2 110 ^ * ] [ 10 3 ^ * ] [ 2 10 ^ * ] ]
: map-suffix ( seq -- seq' ) [ suffix>quot ] [ ] map-as ;
 
! Tests whether a string is composed of metric and/or binary
! suffixes. e.g. "Vikki" -> t
: compound? ( str -- ? )
>upper metric concat "I" append without empty? ;
 
! Convert a float to an integer if it is numerically equivalent
! to an integer. e.g. 1.0 -> 1, 1.23 -> 1.23
: ?f>i ( x -- y/n )
dup >integer 2dup [ number= ] 2dip swap ? ;
 
! Convert a suffix string to a function that performs the
! calculations required by the suffix.
! e.g. "!!!" -> [ 3 m! ], "kiKI" -> [ 2 10 ^ * 2 10 ^ * ]
: parse-suffix ( str -- quot )
{
{ [ dup empty? ] [ drop [ ] ] }
{ [ dup first CHAR: ! = ] [ length [ m! ] curry ] }
{ [ dup compound? ] [ split-compound map-suffix ] }
[ alpha>quot ]
} cond flatten ;
 
GENERIC: commas ( n -- str )
 
! Add commas to an integer in triplets.
! e.g. 1567 -> "1,567"
M: integer commas number>string <reversed> 3 group
[ "," append ] map concat reverse rest ;
 
! Add commas to a float in triplets.
! e.g. 1567.12345 -> "1,567.12345"
M: float commas number>string "." split first2
[ string>number commas ] dip "." glue ;
 
! Parse any number with any numerical or alphabetical suffix.
! e.g. "288Doz" -> "3,456", "9!!" -> "945"
: parse-alpha ( str -- str' )
num/suffix parse-suffix curry call( -- x ) ?f>i commas ;
 
: main ( -- )
test-cases [
dup [ parse-alpha ] map
"Numbers: %[%s, %]\n Result: %[%s, %]\n\n" printf
] each ;
 
MAIN: main</syntaxhighlight>
{{out}}
<pre>
Numbers: { 2greatGRo, 24Gros, 288Doz, 1,728pairs, 172.8SCOre }
Result: { 3,456, 3,456, 3,456, 3,456, 3,456 }
 
Numbers: { 1,567, +1.567k, 0.1567e-2m }
Result: { 1,567, 1,567, 1,567 }
 
Numbers: { 25.123kK, 25.123m, 2.5123e-00002G }
Result: { 25,123,000, 25,123,000, 25,123,000 }
 
Numbers: { 25.123kiKI, 25.123Mi, 2.5123e-00002Gi, +.25123E-7Ei }
Result: { 26,343,374.848, 26,343,374.848, 26,975,615.844352, 28,964,846,960.23782 }
 
Numbers: { -.25123e-34Vikki, 2e-77gooGols }
Result: { -33,394.19493810444, 199,999,999,999,999,983,222,784 }
 
Numbers: { 9!, 9!!, 9!!!, 9!!!!, 9!!!!!, 9!!!!!!, 9!!!!!!!, 9!!!!!!!!, 9!!!!!!!!! }
Result: { 362,880, 945, 162, 45, 36, 27, 18, 9, 9 }
</pre>
 
===EBNF===
This solution uses Factor's extended Backus-Naur form (EBNF) language to define a grammar for parsing numerical/alphabetical suffix numbers. The goal was to describe as much of the suffix-number as possible in a declarative manner, minimizing the use of actions (Factor code that is run on a rule before being added to the abstract syntax tree) and helper functions. The biggest departure from this goal was to parse the metric/binary suffixes based on their index in a collection, as this method is less verbose than defining a rule for each suffix.
<syntaxhighlight lang="factor">USING: formatting fry grouping kernel literals math
math.functions math.parser math.ranges multiline peg.ebnf
quotations qw sequences sequences.deep splitting strings unicode ;
IN: rosetta-code.numerical-suffixes.ebnf
 
CONSTANT: test-cases {
qw{ 2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre }
qw{ 1,567 +1.567k 0.1567e-2m }
qw{ 25.123kK 25.123m 2.5123e-00002G }
qw{ 25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei }
qw{ -.25123e-34Vikki 2e-77gooGols }
qw{
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!!
9!!!!!!!!!
}
}
 
CONSTANT: metric qw{ K M G T P E Z Y X W V U }
 
: suffix>quot ( str -- quot )
dup [ [ 0 1 ] dip subseq >upper metric index 1 + ] dip
length 1 = [ 3 * '[ 10 _ ^ * ] ] [ 10 * '[ 2 _ ^ * ] ] if ;
 
: ?f>i ( x -- y/n ) dup >integer 2dup [ number= ] 2dip swap ? ;
 
GENERIC: commas ( n -- str )
M: integer commas number>string <reversed> 3 group
[ "," append ] map concat reverse rest ;
 
M: float commas number>string "." split first2
[ string>number commas ] dip "." glue ;
 
EBNF: suffix-num [=[
sign = [+-]
digit = [0-9]
triplet = digit digit digit
commas = (triplet | digit digit | digit) ([,] triplet)+
integer = sign? (commas | digit+)
exp = [Ee] sign? digit+
bfloat = (integer | sign)? [.] digit+ exp?
float = (bfloat | integer exp)
number = (float | integer) => [[ flatten "" like string>number ]]
pairs = [Pp] [Aa] [Ii] [Rr] [s]? => [[ [ 2 * ] ]]
dozens = [Dd] [Oo] [Zz] [e]? [n]? [s]? => [[ [ 12 * ] ]]
scores = [Ss] [Cc] [Oo] [r]? [e]? [s]? => [[ [ 20 * ] ]]
gross = [Gg] [Rr] [o]? [s]? [s]? => [[ [ 144 * ] ]]
gg = [Gg] [Rr] [Ee] [Aa] [Tt] gross => [[ [ 1728 * ] ]]
googols = [Gg] [Oo] [Oo] [Gg] [Oo] [Ll] [s]? => [[ [ $[ 10 100 ^ ] * ] ]]
alpha = (pairs | dozens | scores | gg | gross | googols)
numeric = ([KkMmGgPpEeT-Zt-z] [Ii]?) => [[ flatten "" like suffix>quot ]]
ncompnd = numeric+
fact = [!]+ => [[ length [ neg 1 swap <range> product ] curry ]]
suffix = (alpha | ncompnd | fact)
s-num = number suffix? !(.) =>
[[ >quotation flatten call( -- x ) ?f>i commas ]]
]=]
 
: num-alpha-suffix-demo ( -- )
test-cases [
dup [ suffix-num ] map
"Numbers: %[%s, %]\n Result: %[%s, %]\n\n" printf
] each ;
MAIN: num-alpha-suffix-demo</syntaxhighlight>
{{out}}
<pre>
Numbers: { 2greatGRo, 24Gros, 288Doz, 1,728pairs, 172.8SCOre }
Result: { 3,456, 3,456, 3,456, 3,456, 3,456 }
 
Numbers: { 1,567, +1.567k, 0.1567e-2m }
Result: { 1,567, 1,567, 1,567 }
 
Numbers: { 25.123kK, 25.123m, 2.5123e-00002G }
Result: { 25,123,000, 25,123,000, 25,123,000 }
 
Numbers: { 25.123kiKI, 25.123Mi, 2.5123e-00002Gi, +.25123E-7Ei }
Result: { 26,343,374.848, 26,343,374.848, 26,975,615.844352, 28,964,846,960.23782 }
 
Numbers: { -.25123e-34Vikki, 2e-77gooGols }
Result: { -33,394.19493810444, 199,999,999,999,999,983,222,784 }
 
Numbers: { 9!, 9!!, 9!!!, 9!!!!, 9!!!!!, 9!!!!!!, 9!!!!!!!, 9!!!!!!!!, 9!!!!!!!!! }
Result: { 362,880, 945, 162, 45, 36, 27, 18, 9, 9 }
</pre>
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"math"
"math/big"
"strconv"
"strings"
)
 
type minmult struct {
min int
mult float64
}
 
var abbrevs = map[string]minmult{
"PAIRs": {4, 2}, "SCOres": {3, 20}, "DOZens": {3, 12},
"GRoss": {2, 144}, "GREATGRoss": {7, 1728}, "GOOGOLs": {6, 1e100},
}
 
var metric = map[string]float64{
"K": 1e3, "M": 1e6, "G": 1e9, "T": 1e12, "P": 1e15, "E": 1e18,
"Z": 1e21, "Y": 1e24, "X": 1e27, "W": 1e30, "V": 1e33, "U": 1e36,
}
 
var binary = map[string]float64{
"Ki": b(10), "Mi": b(20), "Gi": b(30), "Ti": b(40), "Pi": b(50), "Ei": b(60),
"Zi": b(70), "Yi": b(80), "Xi": b(90), "Wi": b(100), "Vi": b(110), "Ui": b(120),
}
 
func b(e float64) float64 {
return math.Pow(2, e)
}
 
func googol() *big.Float {
g1 := new(big.Float).SetPrec(500)
g1.SetInt64(10000000000)
g := new(big.Float)
g.Set(g1)
for i := 2; i <= 10; i++ {
g.Mul(g, g1)
}
return g
}
 
func fact(num string, d int) int {
prod := 1
n, _ := strconv.Atoi(num)
for i := n; i > 0; i -= d {
prod *= i
}
return prod
}
 
func parse(number string) *big.Float {
bf := new(big.Float).SetPrec(500)
t1 := new(big.Float).SetPrec(500)
t2 := new(big.Float).SetPrec(500)
// find index of last digit
var i int
for i = len(number) - 1; i >= 0; i-- {
if '0' <= number[i] && number[i] <= '9' {
break
}
}
num := number[:i+1]
num = strings.Replace(num, ",", "", -1) // get rid of any commas
suf := strings.ToUpper(number[i+1:])
if suf == "" {
bf.SetString(num)
return bf
}
if suf[0] == '!' {
prod := fact(num, len(suf))
bf.SetInt64(int64(prod))
return bf
}
for k, v := range abbrevs {
kk := strings.ToUpper(k)
if strings.HasPrefix(kk, suf) && len(suf) >= v.min {
t1.SetString(num)
if k != "GOOGOLs" {
t2.SetFloat64(v.mult)
} else {
t2 = googol() // for greater accuracy
}
bf.Mul(t1, t2)
return bf
}
}
bf.SetString(num)
for k, v := range metric {
for j := 0; j < len(suf); j++ {
if k == suf[j:j+1] {
if j < len(suf)-1 && suf[j+1] == 'I' {
t1.SetFloat64(binary[k+"i"])
bf.Mul(bf, t1)
j++
} else {
t1.SetFloat64(v)
bf.Mul(bf, t1)
}
}
}
}
return bf
}
 
func commatize(s string) string {
if len(s) == 0 {
return ""
}
neg := s[0] == '-'
if neg {
s = s[1:]
}
frac := ""
if ix := strings.Index(s, "."); ix >= 0 {
frac = s[ix:]
s = s[:ix]
}
le := len(s)
for i := le - 3; i >= 1; i -= 3 {
s = s[0:i] + "," + s[i:]
}
if !neg {
return s + frac
}
return "-" + s + frac
}
 
func process(numbers []string) {
fmt.Print("numbers = ")
for _, number := range numbers {
fmt.Printf("%s ", number)
}
fmt.Print("\nresults = ")
for _, number := range numbers {
res := parse(number)
t := res.Text('g', 50)
fmt.Printf("%s ", commatize(t))
}
fmt.Println("\n")
}
 
func main() {
numbers := []string{"2greatGRo", "24Gros", "288Doz", "1,728pairs", "172.8SCOre"}
process(numbers)
 
numbers = []string{"1,567", "+1.567k", "0.1567e-2m"}
process(numbers)
 
numbers = []string{"25.123kK", "25.123m", "2.5123e-00002G"}
process(numbers)
 
numbers = []string{"25.123kiKI", "25.123Mi", "2.5123e-00002Gi", "+.25123E-7Ei"}
process(numbers)
 
numbers = []string{"-.25123e-34Vikki", "2e-77gooGols"}
process(numbers)
 
numbers = []string{"9!", "9!!", "9!!!", "9!!!!", "9!!!!!", "9!!!!!!",
"9!!!!!!!", "9!!!!!!!!", "9!!!!!!!!!"}
process(numbers)
}</syntaxhighlight>
 
{{out}}
<pre>
numbers = 2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre
results = 3,456 3,456 3,456 3,456 3,456
 
numbers = 1,567 +1.567k 0.1567e-2m
results = 1,567 1,567 1,567
 
numbers = 25.123kK 25.123m 2.5123e-00002G
results = 25,123,000 25,123,000 25,123,000
 
numbers = 25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei
results = 26,343,374.848 26,343,374.848 26,975,615.844352 28,964,846,960.237816578048
 
numbers = -.25123e-34Vikki 2e-77gooGols
results = -33,394.194938104441474962344775423096782848 200,000,000,000,000,000,000,000
 
numbers = 9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
results = 362,880 945 162 45 36 27 18 9 9
</pre>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Formatting
 
partialsuffixes = Dict("PAIR" => "PAIRS", "SCO" => "SCORES", "DOZ" => "DOZENS",
"GR" => "GROSS", "GREATGR" => "GREATGROSS", "GOOGOL" => "GOOGOLS")
partials = sort(collect(keys(partialsuffixes)), lt=(a,b)->length(a)<length(b), rev=true)
 
multicharsuffixes = Dict("PAIRS" => 2, "SCORES" => 20, "DOZENS" => 12, "GROSS" => 144,
"GREATGROSS" => 1728, "GOOGOLS" => BigInt(10)^100)
 
twocharsuffixes = Dict(
"KI" => BigInt(2)^10, "MI" => BigInt(2)^20, "GI" => BigInt(2)^30, "TI" => BigInt(2)^40,
"PI" => BigInt(2)^50, "EI" => BigInt(2)^60, "ZI" => BigInt(2)^70, "YI" => BigInt(2)^80,
"XI" => BigInt(2)^90, "WI" => BigInt(2)^100, "VI" => BigInt(2)^110, "UI" => BigInt(2)^120)
twosuff = collect(keys(twocharsuffixes))
 
onecharsuffixes = Dict("K" => 10^3, "M" => 10^6, "G" => 10^9, "T" => 10^12, "P" => 10^15,
"E" => 10^18, "Z" => 10^21, "Y" => BigInt(10)^24,
"X" => BigInt(10)^27, "W" => BigInt(10)^30,
"V" => BigInt(10)^33, "U" => BigInt(10)^36)
onesuff = collect(keys(onecharsuffixes))
 
function firstsuffix(s, x)
str = uppercase(s)
if str[1] == '!'
lastbang = something(findfirst(x -> x != '!', str), length(str))
return prod(x:-lastbang:1) / x, lastbang
end
for pstr in partials
if match(Regex("^" * pstr), str) != nothing
fullsuffix = partialsuffixes[pstr]
n = length(pstr)
while n < length(fullsuffix) && n < length(str) && fullsuffix[n+1] == str[n+1]
n += 1
end
return BigInt(multicharsuffixes[fullsuffix]), n
end
end
for pstr in twosuff
if match(Regex("^" * pstr), str) != nothing
return BigInt(twocharsuffixes[pstr]), 2
end
end
for pstr in onesuff
if match(Regex("^" * pstr), str) != nothing
return BigInt(onecharsuffixes[pstr]), 1
end
end
return 1, length(s)
end
 
function parsesuffix(s, x)
str = s
mult = BigInt(1)
n = 1
while n <= length(str)
multiplier, n = firstsuffix(str, x)
mult *= multiplier
str = str[n+1:end]
end
mult
end
 
function suffixednumber(s)
if (endnum = findlast(isdigit, s)) == nothing
return NaN
end
x = BigFloat(replace(s[1:endnum], "," => ""))
return x * (endnum < length(s) ? parsesuffix(s[endnum + 1:end], x) : 1)
end
 
const testcases =
["2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre",
"1,567 +1.567k 0.1567e-2m",
"25.123kK 25.123m 2.5123e-00002G",
"25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei",
"-.25123e-34Vikki 2e-77gooGols",
"9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!"]
 
function testsuffixes()
for line in testcases
cases = split(line)
println("Testing: ", string.(cases))
println("Results: ", join(map(x -> format(suffixednumber(x), commas=true), cases), " "), "\n")
end
end
 
testsuffixes()
</syntaxhighlight>{{out}}
<pre>
Testing: ["2greatGRo", "24Gros", "288Doz", "1,728pairs", "172.8SCOre"]
Results: 3,456 3,456 3,456 3,456 3,456
 
Testing: ["1,567", "+1.567k", "0.1567e-2m"]
Results: 1,567 1,567 1,567
 
Testing: ["25.123kK", "25.123m", "2.5123e-00002G"]
Results: 25,123,000 25,123,000 25,123,000
 
Testing: ["25.123kiKI", "25.123Mi", "2.5123e-00002Gi", "+.25123E-7Ei"]
Results: 26,343,374.848 26,343,374.848 26,975,615.844352 28,964,846,960.237817
 
Testing: ["-.25123e-34Vikki", "2e-77gooGols"]
Results: -33,394.194938 200,000,000,000,000,000,000,000
 
Testing: ["9!", "9!!", "9!!!", "9!!!!", "9!!!!!", "9!!!!!!", "9!!!!!!!", "9!!!!!!!!", "9!!!!!!!!!"]
Results: 362,880 945 162 45 36 27 18 9 9
</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import re, strutils, parseutils, tables, math
const input = """
2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre
1,567 +1.567k 0.1567e-2m
25.123kK 25.123m 2.5123e-00002G
25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei
-.25123e-34Vikki 2e-77gooGols
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
"""
let
abbrAlpha = re(r"(PAIR)(s)?$|(SCO)(r|re|res)?$|(DOZ)(e|en|ens)?$|(GR)(o|os|oss)?$|(GREATGR)(o|os|oss)?$|(GOOGOL)(s)?$",
flags = {reIgnoreCase})
metricBinary = re(r"[KMGTPEZYXWVU]i?", flags = {reIgnoreCase})
factorial = re"!+$"
const
alphaValues = [2e0, 20e0, 12e0, 144e0, 1728e0, 1e100]
metricBinaryValueTab = {"K": 10.0^3, "KI": 2.0^10, "M": 10.0^6, "MI": 2.0^20,
"G": 10.0^9, "GI": 2.0^30, "T": 10.0^12, "TI": 2.0^40, "P": 10.0^15,
"PI": 2.0^50, "E": 10.0^18, "EI": 2.0^60, "Z": 10.0^21, "ZI": 2.0^70,
"Y": 10.0^24, "YI": 2.0^80, "X": 10.0^27, "XI": 2.0^90, "W": 10.0^30,
"WI": 2.0^100, "V": 10.0^33, "VI": 2.0^110, "U": 10.0^36,
"UI": 2.0^120}.toTable
var
matches: array[12, string]
res, fac: float
suffix: string
proc sepFloat(f: float): string =
var
s = $f
i, num: int
num = parseInt(s, i)
if num == 0:
return s
else:
return insertSep($i, ',', 3)&s[num..^1]
for line in input.splitLines():
if not isEmptyOrWhiteSpace(line):
echo("Input:\n", line, "\nOutput:")
var output = " "
for raw_number in line.replace(",", "").splitWhiteSpace():
suffix = raw_number[parseutils.parseFloat(raw_number, res)..^1].toUpper()
if suffix.match(abbrAlpha, matches):
for i, v in matches.mpairs():
if i mod 2 == 0 and not v.isEmptyOrWhiteSpace():
res*=alphaValues[i div 2]
v = ""
break
elif suffix.match(factorial):
fac = abs(res)-toFloat(len(suffix))
while fac > 0:
res*=fac
fac-=toFloat(len(suffix))
elif suffix.match(metricBinary):
for m in suffix.findAll(metricBinary):
res*=metricBinaryValueTab[m]
output &= sepFloat(res)&" "
echo(output)
</syntaxhighlight>
{{out}}<pre>
Input:
2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre
Output:
3,456.0 3,456.0 3,456.0 3,456.0 3,456.0
Input:
1,567 +1.567k 0.1567e-2m
Output:
1,567.0 1,567.0 1,567.0
Input:
25.123kK 25.123m 2.5123e-00002G
Output:
25,123,000.0 25,123,000.0 25,123,000.0
Input:
25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei
Output:
26,343,374.848 26,343,374.848 26,975,615.844352 28,964,846,960.23782
Input:
-.25123e-34Vikki 2e-77gooGols
Output:
-33,394.19493810444 2e+23
Input:
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
Output:
362,880.0 945.0 162.0 45.0 36.0 27.0 18.0 9.0 9.0
</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/Numerical_and_alphabetical_suffixes
use warnings;
 
my %suffix = qw( k 1e3 m 1e6 g 1e9 t 1e12 p 1e15 e 1e18 z 1e21 y 1e24 x 1e27
w 1e30 v 1e33 u 1e36 ki 2**10 mi 2**20 gi 2**30 ti 2**40 pi 2**50 ei 2**60
zi 2**70 yi 2**80 xi 2**90 wi 2**100 vi 2**110 ui 2**120 );
 
local $" = ' '; # strange rule...
print "numbers = ${_}results = @{[ map suffix($_), split ]}\n\n" while <DATA>;
 
sub suffix
{
my ($value, $mods) = shift =~ tr/,//dr =~ /([+-]?[\d.]+(?:e[+-]\d+)?)(.*)/i;
$value *= $^R while $mods =~ /
PAIRs? (?{ 2 })
| SCO(re?)? (?{ 20 })
| DOZ(e(ns?)?)? (?{ 12 })
| GREATGR(o(ss?)?)? (?{ 1728 }) # must be before GRoss
| GR(o(ss?)?)? (?{ 144 })
| GOOGOLs? (?{ 10**100 })
| [kmgtpezyxwvu]i? (?{ eval $suffix{ lc $& } })
| !+ (?{ my $factor = $value;
$value *= $factor while ($factor -= length $&) > 1;
1 })
/gix;
return $value =~ s/(\..*)|\B(?=(\d\d\d)+(?!\d))/$1 || ','/ger;
}
 
__DATA__
2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre
1,567 +1.567k 0.1567e-2m
25.123kK 25.123m 2.5123e-00002G
25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei
-.25123e-34Vikki 2e-77gooGols
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!</syntaxhighlight>
{{out}}
<pre>
numbers = 2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre
results = 3,456 3,456 3,456 3,456 3,456
 
numbers = 1,567 +1.567k 0.1567e-2m
results = 1,567 1,567 1,567
 
numbers = 25.123kK 25.123m 2.5123e-00002G
results = 25,123,000 25,123,000 25,123,000
 
numbers = 25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei
results = 26,343,374.848 26,343,374.848 26,975,615.844352 28,964,846,960.2378
 
numbers = -.25123e-34Vikki 2e-77gooGols
results = -33,394.1949381044 2e+23
 
numbers = 9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
results = 362,880 945 162 45 36 27 18 9 9
 
</pre>
 
=={{header|Phix}}==
Using bigatom to get the full precision needed for the tests (esp the "Vikki" one).<br>
Note that comma-insertion was added to ba_sprintf() in version 0.8.0.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">builtins</span><span style="color: #0000FF;">/</span><span style="color: #000000;">bigatom</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_scale</span><span style="color: #0000FF;">(</span><span style="color: #000000;">34</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (min rqd for accuracy on the "Vikki" test)
-- (the default is 25, not quite enough here)</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">suffixes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #008000;">"GREATGRoss"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1728</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"GOOGOLs"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_new</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"1e100"</span><span style="color: #0000FF;">)},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"SCOres"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">20</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"DOZens"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">12</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"GRoss"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">144</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #008000;">"PAIRs"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">},</span>
<span style="color: #008000;">"KMGTPEZYXWVU"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">suffix</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">bigatom</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">BA_ONE</span>
<span style="color: #000000;">suffix</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">suffix</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">suffix</span><span style="color: #0000FF;">)></span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">suffix</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">suffixes</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">suffixes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">and</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">suffixes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">and</span> <span style="color: #000000;">suffix</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #7060A8;">upper</span><span style="color: #0000FF;">(</span><span style="color: #000000;">suffixes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">][</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">suffixes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">][</span><span style="color: #000000;">3</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">suffix</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">suffix</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]</span>
<span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">found</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">found</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">suffix</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">suffixes</span><span style="color: #0000FF;">[$])</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">suffix</span><span style="color: #0000FF;">)>=</span><span style="color: #000000;">2</span> <span style="color: #008080;">and</span> <span style="color: #000000;">suffix</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'I'</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1024</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">suffix</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">suffix</span><span style="color: #0000FF;">[</span><span style="color: #000000;">3</span><span style="color: #0000FF;">..$]</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ba_power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1000</span><span style="color: #0000FF;">,</span><span style="color: #000000;">k</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">suffix</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">suffix</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">..$]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">facto</span><span style="color: #0000FF;">(</span><span style="color: #000000;">bigatom</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">bigatom</span> <span style="color: #000000;">nf</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">ba_compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nf</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)>=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nf</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">nf</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nf</span><span style="color: #0000FF;">,</span><span style="color: #000000;">f</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">n</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">test_cases</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"""
2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre
1,567 +1.567k 0.1567e-2m
25.123kK 25.123m 2.5123e-00002G
25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei
-.25123e-34Vikki 2e-77gooGols
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
0.017k!!
"""</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test_cases</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" "</span><span style="color: #0000FF;">),</span><span style="color: #000000;">no_empty</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">test</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">suffix</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">facts</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">f</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">[</span><span style="color: #000000;">f</span><span style="color: #0000FF;">]!=</span><span style="color: #008000;">'!'</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">test</span><span style="color: #0000FF;">,</span><span style="color: #000000;">facts</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">test</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">f</span><span style="color: #0000FF;">],</span><span style="color: #000000;">test</span><span style="color: #0000FF;">[</span><span style="color: #000000;">f</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]}</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">>=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">and</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;"><=</span><span style="color: #008000;">'9'</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">test</span><span style="color: #0000FF;">,</span><span style="color: #000000;">suffix</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">test</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">d</span><span style="color: #0000FF;">],</span><span style="color: #000000;">test</span><span style="color: #0000FF;">[</span><span style="color: #000000;">d</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$]}</span>
<span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">bigatom</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_new</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">test</span><span style="color: #0000FF;">,</span><span style="color: #008000;">","</span><span style="color: #0000FF;">,</span><span style="color: #008000;">""</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">decode</span><span style="color: #0000FF;">(</span><span style="color: #000000;">suffix</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">facto</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">facts</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">ns</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ba_sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"%,B"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%30s : %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
2greatGRo : 3,456
24Gros : 3,456
288Doz : 3,456
1,728pairs : 3,456
172.8SCOre : 3,456
1,567 : 1,567
+1.567k : 1,567
0.1567e-2m : 1,567
25.123kK : 25,123,000
25.123m : 25,123,000
2.5123e-00002G : 25,123,000
25.123kiKI : 26,343,374.848
25.123Mi : 26,343,374.848
2.5123e-00002Gi : 26,975,615.844352
+.25123E-7Ei : 28,964,846,960.237816578048
-.25123e-34Vikki : -33,394.194938104441474962344775423096782848
2e-77gooGols : 200,000,000,000,000,000,000,000
9! : 362,880
9!! : 945
9!!! : 162
9!!!! : 45
9!!!!! : 36
9!!!!!! : 27
9!!!!!!! : 18
9!!!!!!!! : 9
9!!!!!!!!! : 9
0.017k!! : 34,459,425
</pre>
 
=={{header|Python}}==
{{works with|CPython|3.7.3}}
<syntaxhighlight lang="python">
from functools import reduce
from operator import mul
from decimal import *
 
getcontext().prec = MAX_PREC
 
def expand(num):
suffixes = [
# (name, min_abbreviation_length, base, exponent)
('greatgross', 7, 12, 3),
('gross', 2, 12, 2),
('dozens', 3, 12, 1),
('pairs', 4, 2, 1),
('scores', 3, 20, 1),
('googols', 6, 10, 100),
('ki', 2, 2, 10),
('mi', 2, 2, 20),
('gi', 2, 2, 30),
('ti', 2, 2, 40),
('pi', 2, 2, 50),
('ei', 2, 2, 60),
('zi', 2, 2, 70),
('yi', 2, 2, 80),
('xi', 2, 2, 90),
('wi', 2, 2, 100),
('vi', 2, 2, 110),
('ui', 2, 2, 120),
('k', 1, 10, 3),
('m', 1, 10, 6),
('g', 1, 10, 9),
('t', 1, 10, 12),
('p', 1, 10, 15),
('e', 1, 10, 18),
('z', 1, 10, 21),
('y', 1, 10, 24),
('x', 1, 10, 27),
('w', 1, 10, 30)
]
 
num = num.replace(',', '').strip().lower()
 
if num[-1].isdigit():
return float(num)
 
for i, char in enumerate(reversed(num)):
if char.isdigit():
input_suffix = num[-i:]
num = Decimal(num[:-i])
break
 
if input_suffix[0] == '!':
return reduce(mul, range(int(num), 0, -len(input_suffix)))
 
while len(input_suffix) > 0:
for suffix, min_abbrev, base, power in suffixes:
if input_suffix[:min_abbrev] == suffix[:min_abbrev]:
for i in range(min_abbrev, len(input_suffix) + 1):
if input_suffix[:i+1] != suffix[:i+1]:
num *= base ** power
input_suffix = input_suffix[i:]
break
break
 
return num
 
 
test = "2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre\n\
1,567 +1.567k 0.1567e-2m\n\
25.123kK 25.123m 2.5123e-00002G\n\
25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei\n\
-.25123e-34Vikki 2e-77gooGols\n\
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!"
 
for test_line in test.split("\n"):
test_cases = test_line.split()
print("Input:", ' '.join(test_cases))
print("Output:", ' '.join(format(result, ',f').strip('0').strip('.') for result in map(expand, test_cases)))
</syntaxhighlight>
{{out}}
<pre>
Input: 2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre
Output: 3,456 3,456 3,456 3,456 3,456
Input: 1,567 +1.567k 0.1567e-2m
Output: 1,567 1,567 1,567
Input: 25.123kK 25.123m 2.5123e-00002G
Output: 25,123,000 25,123,000 25,123,000
Input: 25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei
Output: 26,343,374.848 26,343,374.848 26,975,615.844352 28,964,846,960.237816578048
Input: -.25123e-34Vikki 2e-77gooGols
Output: -33,394.194938104441474962344775423096782848 200,000,000,000,000,000,000,000
Input: 9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
Output: 362,880 945 162 45 36 27 18 9 9
</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.09}}
Scientific notation, while supported in Raku, is limited to IEEE-754 64bit accuracy so there is some rounding on values using it. Implements a custom "high precision" conversion routine.
 
Unfortunately, this suffix routine is of limited use for practical everyday purposes. It focuses on handling excessively large and archaic units (googol, greatgross) and completely ignores or makes unusable (due to forcing case insensitivity) many common current ones: c(centi), m(milli), μ(micro). Ah well.
 
Note: I am blatantly and deliberately ignoring the task guidelines for formatting the output. It has no bearing on the core of the task. If you really, ''really'','' '''REALLY''' ''want to see badly formatted output, uncomment the last line.
 
<syntaxhighlight lang="raku" line>use Rat::Precise;
 
my $googol = 10**100;
«PAIRs 2 SCOres 20 DOZens 12 GRoss 144 GREATGRoss 1728 GOOGOLs $googol»
~~ m:g/ ((<.:Lu>+) <.:Ll>*) \s+ (\S+) /;
 
my %abr = |$/.map: {
my $abbrv = .[0].Str.fc;
my $mag = +.[1];
|map { $abbrv.substr( 0, $_ ) => $mag },
.[0][0].Str.chars .. $abbrv.chars
}
 
my %suffix = flat %abr,
(<K M G T P E Z Y X W V U>».fc Z=> (1000, * * 1000 … *)),
(<Ki Mi Gi Ti Pi Ei Zi Yi Xi Wi Vi Ui>».fc Z=> (1024, * * 1024 … *));
 
my $reg = %suffix.keys.join('|');
 
sub comma ($i is copy) {
my $s = $i < 0 ?? '-' !! '';
my ($whole, $frac) = $i.split('.');
$frac = $frac.defined ?? ".$frac" !! '';
$s ~ $whole.abs.flip.comb(3).join(',').flip ~ $frac
}
 
sub units (Str $str) {
$str.fc ~~ /^(.+?)(<alpha>*)('!'*)$/;
my ($val, $unit, $fact) = $0, $1.Str.fc, $2.Str;
$val.=subst(',', '', :g);
if $val ~~ m:i/'e'/ {
my ($m,$e) = $val.split(/<[eE]>/);
$val = ($e < 0)
?? $m * FatRat.new(1,10**-$e)
!! $m * 10**$e;
}
my @suf = $unit;
unless %suffix{$unit}:exists {
$unit ~~ /(<$reg>)+/;
@suf = $0;
}
my $ret = $val<>;
$ret = [*] $ret, |@suf.map: { %suffix{$_} } if @suf[0];
$ret = [*] ($ret, * - $fact.chars …^ * < 2) if $fact.chars;
$ret.?precise // $ret
}
 
my $test = q:to '===';
2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre
1,567 +1.567k 0.1567e-2m
25.123kK 25.123m 2.5123e-00002G
25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei
-.25123e-34Vikki 2e-77gooGols
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
.017k!!
===
 
printf "%16s: %s\n", $_, comma .&units for $test.words;
 
# Task required stupid layout
# say "\n In: $_\nOut: ", .words.map({comma .&units}).join(' ') for $test.lines;</syntaxhighlight>
{{out}}
<pre> 2greatGRo: 3,456
24Gros: 3,456
288Doz: 3,456
1,728pairs: 3,456
172.8SCOre: 3,456
1,567: 1,567
+1.567k: 1,567
0.1567e-2m: 1,567
25.123kK: 25,123,000
25.123m: 25,123,000
2.5123e-00002G: 25,123,000
25.123kiKI: 26,343,374.848
25.123Mi: 26,343,374.848
2.5123e-00002Gi: 26,975,615.844352
+.25123E-7Ei: 28,964,846,960.237816578048
-.25123e-34Vikki: -33,394.194938104441474962344775423096782848
2e-77gooGols: 200,000,000,000,000,000,000,000
9!: 362,880
9!!: 945
9!!!: 162
9!!!!: 45
9!!!!!: 36
9!!!!!!: 27
9!!!!!!!: 18
9!!!!!!!!: 9
9!!!!!!!!!: 9
.017k!!: 34,459,425</pre>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX pgm converts numbers (with commas) with suffix multipliers──►pure decimal numbers*/
numeric digits 2000 /*allow the usage of ginormous numbers.*/
@.=; @.1= '2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre'
Line 209 ⟶ 1,189:
if \isNum(x) then x= $sfx!(x); if isNum(x) then return x/1
if q==1 then return x
if q=='' then call ser "argument isn't numeric or doesn't have a legal suffix:" x</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 229 ⟶ 1,209:
numbers= 9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
result= 362,880 945 162 45 36 27 18 9 9
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-big}}
{{libheader|Wren-str}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./big" for BigRat
import "./str" for Str
import "./fmt" for Fmt
 
var abbrevs = {
"PAIRs": [4, 2], "SCOres": [3, 20], "DOZens": [3, 12],
"GRoss": [2, 144], "GREATGRoss": [7, 1728], "GOOGOLs": [6, 1e100]
}
 
var metric = {
"K": 1e3, "M": 1e6, "G": 1e9, "T": 1e12, "P": 1e15, "E": 1e18,
"Z": 1e21, "Y": 1e24, "X": 1e27, "W": 1e30, "V": 1e33, "U": 1e36
}
 
var b = Fn.new { |e| BigRat.two.pow(e) }
 
var binary = {
"Ki": b.call(10), "Mi": b.call(20), "Gi": b.call(30), "Ti": b.call(40),
"Pi": b.call(50), "Ei": b.call(60), "Zi": b.call(70), "Yi": b.call(80),
"Xi": b.call(90), "Wi": b.call(100), "Vi": b.call(110), "Ui": b.call(120)
}
 
var googol = BigRat.fromDecimal("1e100")
 
var fact = Fn.new { |num, d|
var prod = 1
var n = Num.fromString(num)
var i = n
while (i > 0) {
prod = prod * i
i = i - d
}
return prod
}
 
var parse = Fn.new { |number|
// find index of last digit
var i = number.count - 1
while (i >= 0) {
if (48 <= number.bytes[i] && number.bytes[i] <= 57) break
i = i - 1
}
var num = number[0..i]
num = num.replace(",", "") // get rid of any commas
var suf = Str.upper(number[i+1..-1])
if (suf == "") return BigRat.fromDecimal(num)
if (suf[0] == "!") {
var prod = fact.call(num, suf.count)
return BigRat.new(prod)
}
for (me in abbrevs) {
var kk = Str.upper(me.key)
if (kk.startsWith(suf) && suf.count >= me.value[0]) {
var t1 = BigRat.fromDecimal(num)
var t2 = (me.key != "GOOGOLS") ? BigRat.fromDecimal(me.value[1]) : googol
return t1 * t2
}
}
var bf = BigRat.fromDecimal(num)
for (me in metric) {
var j = 0
while (j < suf.count) {
if (me.key == suf[j]) {
if (j < suf.count-1 && suf[j+1] == "I") {
bf = bf * binary[me.key + "i"]
j = j + 1
} else {
bf = bf * me.value
}
}
j = j + 1
}
}
return bf
}
 
var process = Fn.new { |numbers|
System.write("numbers = ")
for (number in numbers) Fmt.write("$s ", number)
System.write("\nresults = ")
for (number in numbers) {
var res = parse.call(number)
if (res.isInteger) {
Fmt.write("$,s ", res.toDecimal(50))
} else {
var sres = Fmt.swrite("$,s", res.truncate.toDecimal)
Fmt.write("$s ", sres + res.fraction.abs.toDecimal(50)[1..-1])
}
}
System.print("\n")
}
 
var numbers = ["2greatGRo", "24Gros", "288Doz", "1,728pairs", "172.8SCOre"]
process.call(numbers)
 
numbers = ["1,567", "+1.567k", "0.1567e-2m"]
process.call(numbers)
 
numbers = ["25.123kK", "25.123m", "2.5123e-00002G"]
process.call(numbers)
 
numbers = ["25.123kiKI", "25.123Mi", "2.5123e-00002Gi", "+.25123E-7Ei"]
process.call(numbers)
 
numbers = ["-.25123e-34Vikki", "2e-77gooGols"]
process.call(numbers)
 
numbers = ["9!", "9!!", "9!!!", "9!!!!", "9!!!!!", "9!!!!!!", "9!!!!!!!", "9!!!!!!!!", "9!!!!!!!!!"]
process.call(numbers)</syntaxhighlight>
 
{{out}}
<pre>
numbers = 2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre
results = 3,456 3,456 3,456 3,456 3,456
 
numbers = 1,567 +1.567k 0.1567e-2m
results = 1,567 1,567 1,567
 
numbers = 25.123kK 25.123m 2.5123e-00002G
results = 25,123,000 25,123,000 25,123,000
 
numbers = 25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei
results = 26,343,374.848 26,343,374.848 26,975,615.844352 28,964,846,960.237816578048
 
numbers = -.25123e-34Vikki 2e-77gooGols
results = -33,394.194938104441474962344775423096782848 200,000,000,000,000,000,000,000
 
numbers = 9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
results = 362,880 945 162 45 36 27 18 9 9
</pre>
 
=={{header|zkl}}==
{{libheader|GMP}} GNU Multiple Precision Arithmetic Library (big ints)
Floats are limited to 64 bit IEEE754.
Error checking is nonexistent.
<syntaxhighlight lang="zkl">var [const] BI=Import.lib("zklBigNum"); // GMP
var kRE,kD, aRE,aD;
 
kRE,kD = ki();
aRE,aD = abrevCreate();
 
fcn naSuffixes(numStr){
var [const]
numRE=RegExp(0'^([+-]*\.*\d+[.]*\d*E*[+-]*\d*)^),
bangRE=RegExp(0'^(!+)^);
 
nstr:=(numStr - " ,").toUpper();
numRE.search(nstr);
nstr,r := nstr[numRE.matched[0][1],*], numRE.matched[1];
if(r.matches("*[.E]*")) r=r.toFloat(); // arg!
if(r.matches("*[.E]*")) r=r.toFloat(); // arg!
else r=BI(r);
 
reg z;
do{
z=nstr; // use this to see if we actually did anything
if(aRE.search(nstr)){
ns,k := aRE.matched; // ((0,3),"SCO")
re,b := aD[k]; // (RegExp("R|RE|RES"),BI(20)),
nstr = nstr[ns[1],*];
if(re.search(nstr)) nstr=nstr[re.matched[0][1],*]; # remove abbrev tail
r=r*b;
continue;
}else if(kRE.search(nstr)){
r*=kD[kRE.matched[1]]; // "K":1000 ...
nstr=nstr[kRE.matched[0][1],*];
continue;
}else if(bangRE.search(nstr)){ // floats are converted to int
n,k,z := r.toInt(), bangRE.matched[0][1], n - k;
r,nstr = BI(n), nstr[k,*];
while(z>0){ r.mul(z); z-=k; }
continue;
}
}while(nstr and z!=nstr);
r
}
 
fcn ki{ // case insensitive: k, ki,
ss:="K M G T P E Z Y X W V U".split();
d:=Dictionary();
ss.zipWith(d.add,[3..3*(ss.len()),3].apply(BI(10).pow)); # E:1e+18
ss.apply("append","I")
.zipWith(d.add,[10..10*(ss.len()),10].apply(BI(2).pow)); # EI:1.15292e+18
re:="([%s]I\\?)".fmt(ss.concat()); // "([KMGTPEZYXWVU]I\?)"
return(RegExp(re),d);
}
fcn abrevCreate{
var upDown=RegExp("([A-Z]+)(.*)");
s:="PAIRs 2; SCOres 20; DOZens 12; GREATGRoss 1728; GRoss 144; GOOGOLs 10e100".split(";");
abrevs,re := Dictionary(), Sink(String);
foreach an in (s){
a,n := an.split();
upDown.search(a);
u,d := upDown.matched[1,2];
d=d.len().pump(List, // "R|RE|RES"
'+(1),d.get.fp(0),"toUpper").reverse().concat("|");
abrevs.add(u,T(RegExp(d),BI(n)));
re.write(u," ");
}
// "PAIR|SCO|DOZ|GR|GREATGR|GOOGOL"
re=RegExp("(%s)".fmt(re.close().strip().replace(" ","|")));
return(re,abrevs);
}</syntaxhighlight>
<syntaxhighlight lang="zkl">foreach na in (T("2greatGRo", "24Gros", "288Doz", "1,728pairs", "172.8SCOre",
"1,567", "+1.567k", "0.1567e-2m",
"25.123kK", "25.123m", "2.5123e-00002G",
"25.123kiKI", "25.123Mi", "2.5123e-00002Gi", "+.25123E-7Ei",
"-.25123e-34Vikki", "2e-77gooGols",
"9!", "9!!", "9!!!", "9!!!!", "9!!!!!", "9!!!!!!",
"9!!!!!!!", "9!!!!!!!!", "9!!!!!!!!!",
"9!!!!!!!!!k", ".017k!!", "4 dozensK", "2 dozen pairs")){
if((r:=naSuffixes(na)).isType(Float)) println("%16s : %,f".fmt(na,r));
else println("%16s : %,d".fmt(na,r));
}</syntaxhighlight>
{{out}}
<pre style="height:45ex">
2greatGRo : 3,456
24Gros : 3,456
288Doz : 3,456
1,728pairs : 3,456
172.8SCOre : 3,456.000000
1,567 : 1,567
+1.567k : 1,567.000000
0.1567e-2m : 1,567.000000
25.123kK : 25,123,000.000000
25.123m : 25,123,000.000000
2.5123e-00002G : 25,123,000.000000
25.123kiKI : 26,343,374.848000
25.123Mi : 26,343,374.848000
2.5123e-00002Gi : 26,975,615.844352
+.25123E-7Ei : 28,964,846,960.237816
-.25123e-34Vikki : -33,394.194938
2e-77gooGols : 1,999,999,999,999,999,698,010,112.000000
9! : 362,880
9!! : 945
9!!! : 162
9!!!! : 45
9!!!!! : 36
9!!!!!! : 27
9!!!!!!! : 18
9!!!!!!!! : 9
9!!!!!!!!! : 9
9!!!!!!!!!k : 9,000
.017k!! : 34,459,425
4 dozensK : 48,000
2 dozen pairs : 48
</pre>
9,476

edits