90 lines
2.5 KiB
Python
90 lines
2.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""人民币金额转中文大写。"""
|
|
|
|
|
|
def amount_to_cn(amount):
|
|
"""1234.56 -> 壹仟贰佰叁拾肆元伍角陆分"""
|
|
digits = u"零壹贰叁肆伍陆柒捌玖"
|
|
units = [u"", u"拾", u"佰", u"仟"]
|
|
big_units = [u"", u"万", u"亿", u"兆"]
|
|
|
|
try:
|
|
amount = round(float(amount) + 0.0, 2)
|
|
except (TypeError, ValueError):
|
|
return u"零元整"
|
|
|
|
negative = amount < 0
|
|
amount = abs(amount)
|
|
integer_part = int(amount)
|
|
# 避免浮点误差:分位用字符串处理
|
|
fen = int(round((amount - integer_part) * 100))
|
|
if fen == 100:
|
|
integer_part += 1
|
|
fen = 0
|
|
|
|
def int_section(num):
|
|
"""0-9999 转中文"""
|
|
s = u""
|
|
zero_flag = False
|
|
str_num = "%04d" % num
|
|
for i, ch in enumerate(str_num):
|
|
d = int(ch)
|
|
pos = 3 - i
|
|
if d == 0:
|
|
zero_flag = True
|
|
else:
|
|
if zero_flag and s:
|
|
s += digits[0]
|
|
zero_flag = False
|
|
s += digits[d] + units[pos]
|
|
return s
|
|
|
|
if integer_part == 0:
|
|
result = u""
|
|
else:
|
|
sections = []
|
|
n = integer_part
|
|
while n > 0:
|
|
sections.append(n % 10000)
|
|
n //= 10000
|
|
parts = []
|
|
for idx, sec in enumerate(sections):
|
|
if sec == 0:
|
|
parts.append(u"")
|
|
continue
|
|
parts.append(int_section(sec) + big_units[idx])
|
|
result = u""
|
|
for idx in range(len(parts) - 1, -1, -1):
|
|
p = parts[idx]
|
|
if not p:
|
|
if result and not result.endswith(digits[0]):
|
|
result += digits[0]
|
|
continue
|
|
if result and idx < len(parts) - 1 and sections[idx] < 1000:
|
|
result += digits[0]
|
|
result += p
|
|
result = result.rstrip(digits[0]) or u"零"
|
|
|
|
if fen == 0:
|
|
result += u"元整" if result else u"零元整"
|
|
else:
|
|
jiao = fen // 10
|
|
f = fen % 10
|
|
if result:
|
|
result += u"元"
|
|
if jiao:
|
|
result += digits[jiao] + u"角"
|
|
elif f and result:
|
|
result += digits[0]
|
|
if f:
|
|
result += digits[f] + u"分"
|
|
if negative:
|
|
result = u"负" + result
|
|
return result
|
|
|
|
|
|
if __name__ == "__main__":
|
|
for v in (0, 0.05, 0.5, 1, 10, 100.5, 1234.56, 10000, 1002003, 20340.07,
|
|
100000000, 10500.5):
|
|
print(v, amount_to_cn(v))
|