Suffixation of decimal numbers: Difference between revisions
Added FreeBASIC
m (→{{header|Phix}}: added syntax colouring the hard way) |
(Added FreeBASIC) |
||
(3 intermediate revisions by 3 users not shown) | |||
Line 122:
{{trans|Python}}
<
V suffixes = [‘’, ‘K’, ‘M’, ‘G’, ‘T’, ‘P’, ‘E’, ‘Z’, ‘Y’, ‘X’, ‘W’, ‘V’, ‘U’, ‘googol’]
Line 165:
p(‘456,789,100,000.000e+00’, 0, 10)
p(‘+16777216’, -1, 2)
p(‘1.2e101’)</
{{out}}
Line 179:
1.2e101 : 12googol
</pre>
=={{header|C#}}==
{{trans|Python}}
<syntaxhighlight lang="C#">
using System;
using System.Globalization;
public class NumberSuffixer
{
private static readonly string[] Suffixes = { "", "K", "M", "G", "T", "P", "E", "Z", "Y", "X", "W", "V", "U", "googol" };
public static string Suffize(string num, int? digits = null, int baseNum = 10)
{
int exponentDistance = baseNum == 2 ? 10 : 3;
num = num.Trim().Replace(",", "");
string numSign = num[0] == '+' || num[0] == '-' ? num.Substring(0, 1) : "";
num = numSign != "" ? num.Substring(1) : num;
double number = Math.Abs(double.Parse(num, CultureInfo.InvariantCulture));
int suffixIndex;
if (baseNum == 10 && number >= 1e100)
{
suffixIndex = 13;
number /= 1e100;
}
else if (number > 1)
{
double magnitude = Math.Floor(Math.Log(number, baseNum));
suffixIndex = Math.Min((int)Math.Floor(magnitude / exponentDistance), 12);
number /= Math.Pow(baseNum, exponentDistance * suffixIndex);
}
else
{
suffixIndex = 0;
}
string numStr;
if (digits.HasValue)
{
numStr = number.ToString($"F{digits}", CultureInfo.InvariantCulture);
}
else
{
numStr = number.ToString("F3", CultureInfo.InvariantCulture).TrimEnd('0').TrimEnd('.');
}
return numSign + numStr + Suffixes[suffixIndex] + (baseNum == 2 ? "i" : "");
}
public static void Main(string[] args)
{
var tests = new (string, int?, int?)[]
{
("87,654,321", null, null),
("-998,877,665,544,332,211,000", 3, null),
("+112,233", 0, null),
("16,777,216", 1, null),
("456,789,100,000,000", 2, null),
("456,789,100,000,000", 2, 10),
("456,789,100,000,000", 5, 2),
("456,789,100,000.000e+00", 0, 10),
("+16777216", null, 2),
("1.2e101", null, null),
};
foreach (var test in tests)
{
Console.WriteLine($"{test.Item1}, {test.Item2?.ToString() ?? "null"}, {test.Item3?.ToString() ?? "null"} : " +
$"{Suffize(test.Item1, test.Item2, test.Item3 ?? 10)}");
}
}
}
</syntaxhighlight>
{{out}}
<pre>
87,654,321, null, null : 87.654M
-998,877,665,544,332,211,000, 3, null : -998.878E
+112,233, 0, null : +112K
16,777,216, 1, null : 16.8M
456,789,100,000,000, 2, null : 456.79T
456,789,100,000,000, 2, 10 : 456.79T
456,789,100,000,000, 5, 2 : 415.44727Ti
456,789,100,000.000e+00, 0, 10 : 457G
+16777216, null, 2 : +16Mi
1.2e101, null, null : 12googol
</pre>
=={{header|FreeBASIC}}==
{{trans|Nim}}
<syntaxhighlight lang="vbnet">#include "string.bi"
#define MIN(a, b) iif((a) < (b), (a), (b))
Dim Shared As String*6 Suffixes(13) = {"", "K", "M", "G", "T", "P", "E", "Z", "Y", "X", "W", "V", "U", "googol"}
Function ReplaceString(Byval s As String, Byval find As String, Byval replaceWith As String) As String
Dim posic As Integer
posic = Instr(s, find)
While posic > 0
s = Left(s, posic - 1) & replaceWith & Mid(s, posic + Len(find))
posic = Instr(posic + Len(replaceWith), s, find)
Wend
Return s
End Function
Function suffize(num As String, digits As Integer, bbase As Integer) As String
Dim As Integer exponentDist
exponentDist = Iif(bbase = 2, 10, 3)
Dim As String numSign = ""
If Left(num, 1) = "+" Or Left(num, 1) = "-" Then
numSign = Left(num, 1)
num = Mid(num, 2)
End If
num = ReplaceString(num, ",", "")
Dim As Double n = Val(num)
Dim As Integer suffixIndex
If bbase = 10 And n >= 1e100 Then
suffixIndex = 13
n /= 1e100
Elseif n > 1 Then
Dim As Integer magnitude = Int(Log(n) / Log(bbase))
suffixIndex = MIN(magnitude \ exponentDist, 12)
n /= bbase ^ (exponentDist * suffixIndex)
Else
suffixIndex = 0
End If
Dim As String numStr
If digits > 0 Then
numStr = Format(n, "0." & String(digits, "#"))
Elseif digits = 0 Then
numStr = Format(Int(n), "0")
Else
numStr = Format(n, "0.###")
End If
Return numSign & numStr & Suffixes(suffixIndex) & Iif(bbase = 2, "i", "")
End Function
Print "[87,654,321]: "; suffize("87,654,321", 3, 10)
Print "[-998,877,665,544,332,211,000 / digits = 3]: "; suffize("-998877665544332211000", 3, 10)
Print "[+112,233 / digits = 0]: "; suffize("+112233", 0, 10)
Print "[16,777,216 / digits = 1]: "; suffize("16777216", 1, 10)
Print "[456,789,100,000,000 / digits = 2]: "; suffize("456789100000000", 2, 10)
Print "[456,789,100,000,000 / digits = 2 / base = 10]: "; suffize("456789100000000", 2, 10)
Print "[456,789,100,000,000 / digits = 5 / base = 2]: "; suffize("456789100000000", 5, 2)
Print "[456,789,100,000.000e+000 / digits = 0 / base = 10]: "; suffize("456789100000", 0, 10)
Print "[+16777216 / base = 2]: "; suffize("+16777216", 3, 2)
Print "[1.2e101]: "; suffize("1.2e101", 3, 10)
Sleep</syntaxhighlight>
=={{header|Go}}==
As go doesn't support either function overloading or optional arguments, we just pass a single string to the suffize function and then split out what we need.
<
import (
Line 300 ⟶ 457:
suffize(test)
}
}</
{{out}}
Line 371 ⟶ 528:
=={{header|Julia}}==
<
const suf = Dict{BigInt, String}(BigInt(1) => "", BigInt(10)^100 => "googol",
Line 432 ⟶ 589:
(n > 2) ? lpad(l[3], 3) : " ", " : ", s)
end
</
<pre>
87,654,321 : 87.654321M
Line 448 ⟶ 605:
=={{header|Nim}}==
{{trans|Python}}
<
const
Line 504 ⟶ 661:
suffize("+16777216", base = 2)
echo "[1.2e101]: ",
suffize("1.2e101")</
{{out}}
Line 520 ⟶ 677:
=={{header|Perl}}==
{{trans|Raku}}
<
sub sufficate {
Line 597 ⟶ 754:
);
printf "%33s : %s\n", $_, sufficate(split ' ', $_) for @tests;</
{{out}}
<pre> 87,654,321 : 87.654321M
Line 618 ⟶ 775:
at least with any fraction that is not an exact sum of half, quarter, etc, so for
that reason this uses bigatom, since that can hold numbers with absolute accuracy.
<!--<
<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>
Line 680 ⟶ 837:
<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;">ti</span><span style="color: #0000FF;">,</span><span style="color: #000000;">res</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</
{{out}}
<pre>
Line 701 ⟶ 858:
Tested in Python 3.7.3<br />
Chose 3 places after decimal (where applicable) as default rounding precision. Number to suffize taken as a string. There are some edge cases where this fails due to binary arithmetic differing from decimal arithmetic and things not rounding nicely.
<
import math
import os
Line 746 ⟶ 903:
for test in tests:
print(' '.join(str(i) for i in test) + ' : ' + suffize(*test))
</syntaxhighlight>
{{out}}
Line 773 ⟶ 930:
If you desire the number to be rounded, pass in a number representing the placed past the decimal to round to. If you pass in a negative number for rounding, it will round to a negative number of places past the decimal.
<syntaxhighlight lang="raku"
if +$type ~~ Int { $round = $type; $type = 'M' }
my $s = '';
Line 825 ⟶ 982:
;
printf "%33s : %s\n", $_, sufficate(|.words) for @tests;</
{{out}}
<pre> 87,654,321 : 87.654321M
Line 842 ⟶ 999:
=={{header|REXX}}==
<
@.= /*default value for the stemmed array. */
parse arg @.1 /*obtain optional arguments from the CL*/
Line 904 ⟶ 1,061:
if n=0 then j=0 /*N = 0? Don't use any suffix. */
return sig||strip(n||substr(@, j+1,1))!.b /*add sign, suffixes, strip blanks.*/</
{{out|output|text= when using the internal default inputs:}}
Line 969 ⟶ 1,126:
=={{header|VBA}}==
VBA has support for 64 bit integers on 64 bit platforms. The program below was developed on a 32 bit platform.
<
Dim suffix As String, parts() As String, exponent As String
Dim fractiondigits As Integer, nsuffix As Integer, flag As Boolean
Line 1,104 ⟶ 1,261:
Debug.Print " new number = "; suffize(tt(0), f, r)
Next i
End Sub</
{{out|output|text= when using the internal default inputs:}}
<pre>------------------------------------------------
Line 1,161 ⟶ 1,318:
{{libheader|Wren-big}}
{{libheader|Wren-fmt}}
<
import "./fmt" for Fmt
var suffixes = " KMGTPEZYXWVU"
Line 1,240 ⟶ 1,397:
"1e39", // there isn't a big enough suffix for this one but it's less than googol
]
for (test in tests) suffize.call(test)</
{{out}}
Line 1,313 ⟶ 1,470:
{{libheader|GMP}} GNU Multiple Precision Arithmetic Library (big ints)
Error checking is nonexistent.
<
var metric, binary, googol=BI("1e100");
metric,binary = metricBin();
Line 1,357 ⟶ 1,514:
.zipWith(b.append,[10..10*(ss.len()),10].apply(BI(2).pow)); // Binary
return(m.filter22("".isType), b.filter22("".isType)); # split to ((strings),(nums))
}</
<
"87,654,321",
"-998,877,665,544,332,211,000 3",
Line 1,380 ⟶ 1,537:
test=test.split();
"%33s : %s".fmt(test.concat(" "),sufficate(test.xplode())).println();
}</
{{out}}
<pre>
|