# -*- 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))