PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/moul/kit/num/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
moul / kit / num
Files
4 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/moul/kit/num/v0
gno
0.9

Files (4)

  • README.mdmarkdown
  • gnomod.tomltoml
  • num.gnogno
  • num_test.gnogno
num.gnogno
1// Package num formats numbers for a human to read: fixed-point amounts,2// percentages and zero padding.3//4// Thousands separators are NOT here. They belong to5// [p/moul/x/daily/humanize](/p/moul/x/daily/humanize/v1), which already owns6// Comma, Bytes, Ordinal, Plural and Blocks.7//8// It exists because nothing in p/moul or p/nt did. Measured across the 8289// .gno files deployed on gnoland-1 by someone other than moul, five10// independent teams wrote their own ugnot-to-GNOT formatter, and the two that11// are byte-level cousins disagree on every input that is not positive. The12// README carries the full table.13//14// # The contract15//16// Every function here is total: no input panics, including the int64 minimum,17// and no input returns a malformed string. That is the whole point of the18// package, because it is precisely where the hand-rolled copies fail.19//20// # Where the decimals come from21//22// gno.land denominates GNOT in ugnot, one millionth of a GNOT, so [GNOT] is23// [Dec] with decimals = 6. A GRC20 token declares its own decimals; pass that24// to [Dec] rather than assuming six.25package num2627import (28	"strconv"29	"strings"30)3132// GnotDecimals is the number of decimal places between ugnot and GNOT.33const GnotDecimals = 63435// maxDecimals caps the scale [Dec] accepts. An int64 holds at most 19 decimal36// digits, so beyond that every value is pure fraction and the cap costs37// nothing real while keeping the padding loop bounded.38const maxDecimals = 193940// Dec renders v as a fixed-point decimal with the given number of places,41// trailing zeros trimmed: Dec(1234500, 6) is "1.2345", Dec(2000000, 6) is "2".42//43// The sign is carried on the whole part, so Dec(-1, 6) is "-0.000001" and not44// "0.999999". Dec panics only on a negative or out-of-range decimals, which is45// a programming error rather than a value.46func Dec(v int64, decimals int) string {47	return dec(v, decimals, false)48}4950// DecFixed is [Dec] without the trailing-zero trim, so every value renders at51// the same width: DecFixed(2000000, 6) is "2.000000". Use it in a column.52func DecFixed(v int64, decimals int) string {53	return dec(v, decimals, true)54}5556// GNOT renders an amount in ugnot as GNOT, with no unit: "1.234567".57func GNOT(ugnot int64) string { return Dec(ugnot, GnotDecimals) }5859// GNOTf is [GNOT] with the unit appended: "1.234567 GNOT".60func GNOTf(ugnot int64) string { return GNOT(ugnot) + " GNOT" }6162// Pct renders basis points as a percentage: Pct(1234) is "12.34%".63// One basis point is a hundredth of a percent, which is the unit every fee on64// this chain is already quoted in.65func Pct(bps int64) string { return Dec(bps, 2) + "%" }6667// Pad renders v in base 10, left-padded with zeros to at least width68// characters: Pad(7, 3) is "007". A negative value keeps its sign outside the69// padding, so Pad(-7, 3) is "-007" and the string is width+1 long.70//71// It exists because ufmt supports no width flags: ufmt.Sprintf("%03d", 7)72// returns "7", silently.73//74// Pad is for DISPLAY. For an avl key that must sort in insertion order, use75// [p/moul/kit/store](/p/moul/kit/store/v0), which has no ceiling to overflow.76func Pad(v int64, width int) string {77	neg, m := mag(v)78	s := strconv.FormatUint(m, 10)79	if n := width - len(s); n > 0 {80		s = strings.Repeat("0", n) + s81	}82	if neg {83		return "-" + s84	}85	return s86}8788func dec(v int64, decimals int, fixed bool) string {89	if decimals < 0 || decimals > maxDecimals {90		panic("num: decimals out of range [0, 19]")91	}92	neg, m := mag(v)93	sign := ""94	if neg {95		sign = "-"96	}97	if decimals == 0 {98		return sign + strconv.FormatUint(m, 10)99	}100101	digits := strconv.FormatUint(m, 10)102	if n := decimals + 1 - len(digits); n > 0 {103		digits = strings.Repeat("0", n) + digits104	}105	cut := len(digits) - decimals106	whole, frac := digits[:cut], digits[cut:]107108	if !fixed {109		frac = strings.TrimRight(frac, "0")110		if frac == "" {111			return sign + whole112		}113	}114	return sign + whole + "." + frac115}116117// mag splits v into a sign and an unsigned magnitude.118//119// -v on math.MinInt64 is math.MinInt64 again, so every shape that stays in120// int64 is wrong there: `if v < 0 { v = -v }` silently keeps the value121// negative, and a recursive `return "-" + f(-v)` never terminates at all. Both122// are live on gnoland-1 today; the second halts the realm.123//124// `uint64(-v)` happens to give the right answer by twos-complement wraparound,125// but it gets it from the overflow rather than despite it. -(v+1)+1 never126// overflows, so it does not depend on that.127func mag(v int64) (bool, uint64) {128	if v < 0 {129		return true, uint64(-(v+1)) + 1130	}131	return false, uint64(v)132}133

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.