# 用英文表示(千进制)配置第一行,中文表示(万进制)配置第二行
EXP_WORDS = ["", "K", "M", "G", "T", "P", "E", "Z", "Y", "R", "Q"]
# EXP_WORDS = ["", "万", "亿", "兆", "京", "垓", "秭", "穰", "沟", "涧"]
# 用英文表示(千进制)配置第一行,中文表示(万进制)配置第二行
EXP_SIZE = 3
# EXP_SIZE = 4
# 最小位数,不到此位数会降级显示(如设为2,23000会显示为23000而不是2万)
MIN_DIGITS = 1
# 小数点后有效数字(12.0的0有意义,转换会保留)
DECIMALS = 0
#--------------------------------------------------------------------------
# ● 转换大数字的显示位数
# x : 要转换的数字,必须是整数(Fixnum/Bignum),可正可负
# method : 舍入处理规则,合法取值有5个
# "round" : 四舍五入(默认)1.4=>1 1.5=>2 -1.4=>-1 -1.5=>-2
# "ceil" : 向上取整 1.4=>2 1.5=>2 -1.4=>-1 -1.5=>-1
# "floor" : 向下取整 1.4=>1 1.5=>1 -1.4=>-2 -1.5=>-2
# "trunc" : 向内取整 1.4=>1 1.5=>1 -1.4=>-1 -1.5=>-1
# "away" : 向外取整 1.4=>2 1.5=>2 -1.4=>-2 -1.5=>-2
# (写成不是另外四种取值的字符串,都会以"round"处理)
#--------------------------------------------------------------------------
def convert_number(x, method = "round")
# 负数前置处理
neg = x < 0
# 字符串度量化
str = x.abs.to_s
len = str.length
exp = (len - MIN_DIGITS) / EXP_SIZE
delimit = exp * EXP_SIZE
# 小数点前截取
before = str[0..-delimit - 1].to_i
# 小数点后截取
after = delimit > 0 ? str[-delimit, DECIMALS].to_i : 0
# 进位处理
if delimit > DECIMALS
round = str[-delimit + DECIMALS, 1].to_i
case round
when 0
carry = (method == (neg ? "floor" : "ceil") || method == "away") &&
str[-delimit + DECIMALS + 1..-1].to_i == 0
when 1..4
carry = (method == (neg ? "floor" : "ceil") || method == "away")
when 5..9
carry = (method != (neg ? "ceil" : "floor") && method != "trunc")
end
if carry
after += 1
if after == 10 ** DECIMALS
before += 1
after = 0
end
end
end
# 按有无小数点分别输出
if DECIMALS > 0 and delimit > 0
digits = [DECIMALS, delimit].min
result = sprintf("%d.%0#{digits}d%s", before, after, EXP_WORDS[exp])
else
result = sprintf("%d%s", before, EXP_WORDS[exp])
end
# 负数后置处理,返回
return neg ? "-" + result : result
end