Last active
June 7, 2022 07:52
-
-
Save telatin/79f2eae9b061cbb8a818e66c58feb2e5 to your computer and use it in GitHub Desktop.
Procedure to add a thousands separator to a float [nim]
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://forum.nim-lang.org/t/8162#52466 | |
import strutils | |
proc floatSeparator(f: float, s=","): string = | |
var s = ($f).split('.') | |
s[0] = s[0].insertSep(',') | |
return s.join(".") | |
let | |
nums = @[112122.2, 12121.0, 902112.294, 41240.2, 20.0281] | |
for i in nums: | |
echo i.floatSeparator() | |
#[ | |
112,122.2 | |
12,121.0 | |
902,112.294 | |
41,240.2 | |
20.0281 | |
]# | |
# ------------- | |
import math | |
import strformat | |
# ---------------------------------------------------------------------------------------------------------------------- | |
proc fmtFloat*(value : float, | |
decimals : int, | |
format : string = "", | |
thousandSep: string = ",", | |
decimalSep : string = "."): string = | |
if value != value: | |
return "NaN" | |
elif value == Inf: | |
return "Inf" | |
elif value == NegInf: | |
return "-Inf" | |
let | |
forceSign = format.find('s') >= 0 | |
thousands = format.find('t') >= 0 | |
removeZero = format.find('z') >= 0 | |
var valueStr = "" | |
if decimals >= 0: | |
valueStr.formatValue(round(value, decimals), "." & $decimals & "f") | |
else: | |
valueStr = $value | |
if valueStr[0] == '-': | |
valueStr = valueStr[1 .. ^1] | |
let | |
period = valueStr.find('.') | |
negZero = 1.0 / value == NegInf | |
sign = if value < 0.0 or negZero: "-" elif forceSign: "+" else: "" | |
var | |
integer = "" | |
integerTmp = valueStr[0 .. period - 1] | |
decimal = decimalSep & valueStr[period + 1 .. ^1] | |
if thousands: | |
while true: | |
if integerTmp.len > 3: | |
integer = thousandSep & integerTmp[^3 .. ^1] & integer | |
integerTmp = integerTmp[0 .. ^4] | |
else: | |
integer = integerTmp & integer | |
break | |
else: | |
integer = integerTmp | |
while removeZero: | |
if decimal[^1] == '0': | |
decimal = decimal[0 .. ^2] | |
else: | |
break | |
if decimal == decimalSep: | |
decimal = "" | |
return sign & integer & decimal | |
# ---------------------------------------------------------------------------------------------------------------------- | |
when isMainModule: | |
doAssert fmtFloat( 0.0, 0) == "0" | |
doAssert fmtFloat(-0.0, 0) == "-0" | |
doAssert fmtFloat( 0.0, 0, "s") == "+0" | |
doAssert fmtFloat( 0.0, 0, "stz") == "+0" | |
doAssert fmtFloat(-0.0, 0, "s") == "-0" | |
doAssert fmtFloat(-0.0, 0, "stz") == "-0" | |
doAssert fmtFloat( 0.0, 2) == "0.00" | |
doAssert fmtFloat(-0.0, 2) == "-0.00" | |
doAssert fmtFloat( 0.0, 2, "s") == "+0.00" | |
doAssert fmtFloat(-0.0, 2, "s") == "-0.00" | |
doAssert fmtFloat( 0.0, 2, "sz") == "+0" | |
doAssert fmtFloat(-0.0, 2, "sz") == "-0" | |
doAssert fmtFloat(12_000.758, 0) == "12001" | |
doAssert fmtFloat(12_000.758, 0, "t") == "12,001" | |
doAssert fmtFloat(12_000.758, 0, "st") == "+12,001" | |
doAssert fmtFloat(12_000.758, 0, "stz") == "+12,001" | |
doAssert fmtFloat(12_000.758, 2) == "12000.76" | |
doAssert fmtFloat(12_000.758, 2, "t") == "12,000.76" | |
doAssert fmtFloat(12_000.758, 2, "st") == "+12,000.76" | |
doAssert fmtFloat(12_000.758, 2, "st", ".", ",") == "+12.000,76" | |
doAssert fmtFloat(12_000.758, 5, "t") == "12,000.75800" | |
doAssert fmtFloat(12_000.758, 5, "st") == "+12,000.75800" | |
doAssert fmtFloat(12_000.758, 5, "stz") == "+12,000.758" | |
doAssert fmtFloat(10_000_000.0, 2, "t") == "10,000,000.00" | |
doAssert fmtFloat(10_000_000.0, 2, "st") == "+10,000,000.00" | |
doAssert fmtFloat(10_000_000.0, 2, "tz") == "10,000,000" | |
doAssert fmtFloat(10_000_000.0, 2, "stz") == "+10,000,000" | |
doAssert fmtFloat(-5_000.12345, 0) == "-5000" | |
doAssert fmtFloat(-5_000.12345, 0, "t") == "-5,000" | |
doAssert fmtFloat(-5_000.12345, -1) == "-5000.12345" | |
doAssert fmtFloat(-5_000.12345, -1, "t") == "-5,000.12345" | |
doAssert fmtFloat(-5_000.12345, -1, "tz") == "-5,000.12345" | |
doAssert fmtFloat(NaN, 0) == "NaN" | |
doAssert fmtFloat(Inf, 1) == "Inf" | |
doAssert fmtFloat(NegInf, -1) == "-Inf" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment