Files

93 lines
2.7 KiB
Python

# -*- coding: utf-8 -*-
"""人民币金额转中文大写。"""
from decimal import Decimal, InvalidOperation, ROUND_HALF_UP
def amount_to_cn(amount):
"""1234.56 -> 壹仟贰佰叁拾肆元伍角陆分"""
digits = u"零壹贰叁肆伍陆柒捌玖"
units = [u"", u"拾", u"佰", u"仟"]
big_units = [u"", u"万", u"亿", u"兆"]
try:
amount = Decimal(str(amount)).quantize(Decimal('0.01'), rounding=ROUND_HALF_UP)
if not amount.is_finite():
raise ValueError('金额无效')
except (InvalidOperation, TypeError, ValueError):
return u"零元整"
negative = amount < 0
amount = abs(amount)
integer_part = int(amount)
# 避免浮点误差:分位用字符串处理
fen = int((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 not result.endswith(digits[0]) 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))