///|
/// Exact signed integer cents; no binary floating-point conversion or rounding.
pub fn format_money(cents : Int64) -> String raise NumberError {
if cents < -9999999999999999L || cents > 9999999999999999L {
raise Invalid("amount outside supported range")
}
let n = if cents < 0L { -cents } else { cents }
let names = digits(true)
let mut out = (if cents < 0L { "负" } else { "" }) +
format_integer(n / 100L, financial=true) +
"元"
let jiao = (n / 10L % 10L).to_int()
let fen = (n % 10L).to_int()
if jiao == 0 && fen == 0 {
return out + "整"
}
if jiao > 0 {
out += names[jiao] + "角"
} else if n >= 100L {
out += "零"
}
if fen > 0 {
out += names[fen] + "分"
}
out
}
///|
pub fn parse_decimal_cents(s : String) -> Int64 raise NumberError {
if s == "" || s.length() > 32 {
raise Invalid("invalid amount")
}
let neg = s.has_prefix("-")
let mut whole = 0L
let mut fraction = 0L
let mut count = 0
let mut point = false
let mut whole_digits = 0
for i in (if neg { 1 } else { 0 }).. 57 {
raise Invalid("invalid decimal digit")
}
if point {
count += 1
if count > 2 {
raise Invalid("more than two fractional digits")
}
fraction = fraction * 10L + (c - 48).to_int64()
} else {
whole_digits += 1
whole = whole * 10L + (c - 48).to_int64()
if whole > 99999999999999L {
raise Invalid("amount overflow")
}
}
}
}
if whole_digits == 0 || (point && count == 0) {
raise Invalid("missing digits")
}
if count == 1 {
fraction *= 10L
}
(whole * 100L + fraction) * (if neg { -1L } else { 1L })
}