合作联系微信: w6668263      合作联系电话:177-9238-7426     

数字转换为中文数字


/**
 * 数字转换为中文数字
 * @param {number|string} num 需要转换的数字
 * @param {object} options 配置项
 * @param {boolean} options.uppercase 是否使用大写中文数字(壹贰叁...),默认 false
 * @returns {string} 中文数字字符串
 * @example
 * numberToChinese(0)        // '零'
 * numberToChinese(10)       // '十'
 * numberToChinese(12)       // '十二'
 * numberToChinese(123)      // '一百二十三'
 * numberToChinese(1001)     // '一千零一'
 * numberToChinese(10000)    // '一万'
 * numberToChinese(100010000) // '一亿零一万'
 * numberToChinese(110)      // '一百一十'
 * numberToChinese(123, { uppercase: true }) // '壹佰贰拾叁'
 */
export function numberToChinese(num, options = {}) {
	const { uppercase = false } = options

	// 数字字符映射
	const digits = uppercase
		? ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']
		: ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']

	// 量级映射
	const units = uppercase ? ['', '拾', '佰', '仟'] : ['', '十', '百', '千']
	const bigUnits = ['', '万', '亿', '万亿']

	const n = Math.floor(Number(num))
	if (isNaN(n)) return ''
	if (n === 0) return digits[0]

	let neg = false
	let absNum = n

	if (absNum < 0) {
		neg = true
		absNum = Math.abs(absNum)
	}

	// 将数字按4位一段从低到高拆分
	const segments = []
	while (absNum > 0) {
		segments.push(absNum % 10000)
		absNum = Math.floor(absNum / 10000)
	}

	let result = ''
	let needZero = false // 标记是否需要在下一段前补"零"(段间零)

	for (let s = segments.length - 1; s >= 0; s--) {
		const segment = segments[s]
		if (segment === 0) {
			needZero = true
			continue
		}

		// 段间零:上一段为0或标记需要零
		if (needZero || (s < segments.length - 1 && segment < 1000)) {
			result += digits[0]
			needZero = false
		}

		// 从高位到低位处理4位数
		let hasNonZero = false
		for (let i = 3; i >= 0; i--) {
			const divisor = Math.pow(10, i)
			const d = Math.floor(segment / divisor) % 10
			if (d === 0) {
				if (hasNonZero) {
					// 中间零:前面有非零数字,后面可能还有非零数字
					// 先标记,等遇到下一个非零数字时再输出"零"
					needZero = true
				}
			} else {
				if (needZero) {
					result += digits[0]
					needZero = false
				}
				result += digits[d] + units[i]
				hasNonZero = true
			}
		}

		// 添加大单位(万、亿)
		result += bigUnits[s]
		needZero = false
	}

	// 最高位"一十"省略为"十"
	const prefix = uppercase ? '壹拾' : '一十'
	if (result.startsWith(prefix)) {
		result = result.slice(1)
	}

	return (neg ? '负' : '') + result
}

 

posted on 2026-04-24 13:27  草率的龙果果  阅读(8)  评论(0)    收藏  举报

导航