面试题答案
一键面试实现思路
- 数据类型检查与转换:在进行运算前,先检查操作数的数据类型。对于
BigInt
和Number
类型,要确保它们在运算时类型统一。BigInt
和Number
不能直接混合运算,需要根据具体需求进行转换。例如,如果需要精确处理大整数,将Number
转换为BigInt
;如果允许一定精度损失,将BigInt
转换为Number
。对于字符串类型,要判断其是否可转换为数字,如果可以则进行转换,否则抛出异常。 - 边界情况处理:
- 极端数值:对于
Number
类型,要处理Number.MAX_SAFE_INTEGER
、Number.MIN_SAFE_INTEGER
等边界值。对于BigInt
,要处理极大或极小的整数值。 - 数据类型转换失败:当字符串无法转换为数字时,应抛出明确的错误信息,而不是返回
NaN
导致后续运算结果不准确。
- 极端数值:对于
- 运算顺序:遵循数学中的运算优先级,使用括号明确运算顺序,避免因优先级问题导致错误结果。
关键代码片段示例
function safeEval(expression) {
const tokens = expression.split(/(\d+|\+|\-|\*|\/|%)/).filter(Boolean);
let result;
let currentTokenIndex = 0;
function nextToken() {
return tokens[currentTokenIndex++];
}
function parseNumber() {
const token = nextToken();
if (/^\d+$/.test(token)) {
if (token.length > 16) {
return BigInt(token);
}
return Number(token);
}
throw new Error('Invalid number: ' + token);
}
function parseFactor() {
let value = parseNumber();
while (true) {
const operator = tokens[currentTokenIndex];
if (operator === '*' || operator === '/' || operator === '%') {
nextToken();
const right = parseNumber();
if (typeof value === 'bigint' || typeof right === 'bigint') {
value = typeof value === 'bigint'? value : BigInt(value);
right = typeof right === 'bigint'? right : BigInt(right);
if (operator === '*') value = value * right;
else if (operator === '/') value = value / right;
else value = value % right;
} else {
if (operator === '*') value = value * right;
else if (operator === '/') value = value / right;
else value = value % right;
}
} else {
break;
}
}
return value;
}
function parseExpression() {
let value = parseFactor();
while (true) {
const operator = tokens[currentTokenIndex];
if (operator === '+' || operator === '-') {
nextToken();
const right = parseFactor();
if (typeof value === 'bigint' || typeof right === 'bigint') {
value = typeof value === 'bigint'? value : BigInt(value);
right = typeof right === 'bigint'? right : BigInt(right);
if (operator === '+') value = value + right;
else value = value - right;
} else {
if (operator === '+') value = value + right;
else value = value - right;
}
} else {
break;
}
}
return value;
}
result = parseExpression();
if (currentTokenIndex!== tokens.length) {
throw new Error('Unexpected token at the end of expression');
}
return result;
}
// 使用示例
const complexExpression = '123 + 456 * 789 - 1234567890123456789n';
try {
const result = safeEval(complexExpression);
console.log(result);
} catch (error) {
console.error(error.message);
}
上述代码通过自定义的safeEval
函数来解析并计算包含多种数据类型的算术表达式。首先将表达式拆分为标记(token),然后按照运算优先级进行解析和计算,在运算过程中处理数据类型转换和边界情况。