如何将整数年份拆解为最小的千年、世纪、十年及年份单位?
整数年份拆解为最小数量时间单位的模运算实现
需要实现一个算法,将整数年份(可正可负,代表多少年前/后)拆解为数量最少的时间单位组合,单位包括十亿(billion,109)、百万(million,106)、千年(thousand,1000)、世纪(century,100)、十年(decade,10)、年份(year,1)。例如输入-10248(10248年前),应输出{ thousand: -10, century: -2, decade: -4, year: -8 }。
原代码的核心问题
你提供的代码存在几个关键错误,导致结果不符合预期:
- 处理顺序颠倒:应该从最大量级开始拆解,而非先处理千年。原代码先取
n%1000得到的是余数(比如-10248%1000为-248),完全不符合需求中的单位定义。 - 负数除法处理错误:
Math.floor对负数除法会向下取整,比如Math.floor(-10248/1000)得到-11,但我们需要的是-10(10个千年对应10000年)。 - 单位逻辑错误:年份的计算用
n%1永远为0(因为n是整数),完全不符合需求。
基于模运算的正确实现
正确思路是从大到小遍历时间单位,用整数除法获取当前单位的数量,再通过模运算得到剩余数值继续处理。使用Math.trunc处理整数除法,它会直接截断小数部分,对正负整数都适用。
function breakdownYearToParts(year) { const result = {}; // 定义时间单位及其量级,按从大到小排序 const units = [ { name: 'billion', value: 1000000000 }, { name: 'million', value: 1000000 }, { name: 'thousand', value: 1000 }, { name: 'century', value: 100 }, { name: 'decade', value: 10 }, { name: 'year', value: 1 } ]; let remaining = year; for (const unit of units) { if (remaining === 0) break; // 剩余为0时停止处理 const count = Math.trunc(remaining / unit.value); if (count !== 0) { result[unit.name] = count; remaining = remaining % unit.value; // 取余数得到剩余年份 } } return result; } // 测试示例 console.log(breakdownYearToParts(-10248)); // 输出: { thousand: -10, century: -2, decade: -4, year: -8 } console.log(breakdownYearToParts(2024)); // 输出: { century: 20, decade: 2, year: 4 } console.log(breakdownYearToParts(1500000)); // 输出: { million: 1, thousand: 500 }
代码逻辑说明
- 按从大到小的顺序遍历单位,确保优先拆解大单位,满足「数量最少」的要求。
Math.trunc(remaining / unit.value)计算当前单位的数量,比如-10248 / 1000得到-10.248,截断后为-10,完全符合需求。remaining = remaining % unit.value得到剩余待拆解的年份,比如-10248 % 1000为-248,继续处理下一个单位。- 仅当单位数量不为0时才加入结果对象,避免冗余的0值键。
内容的提问来源于stack exchange,提问作者Lance Pollard
相关产品推荐
相关产品推荐

