---
# System prepended metadata

title: interview

---

# interview

## 在不發生 integer overflow 的情況下讓一組數字做平均計算

錯誤的解決方法:
``` javascript 
const NEW_NUM_MAX_LENGTH = 4;

class NewNumber {
  constructor(originalNumber) {
    this.value = [];
    this.maxNumber = Math.pow(10, NEW_NUM_MAX_LENGTH);
    this.originalNumber = originalNumber;

    if(!Number.isInteger(originalNumber)) throw new Error(`Original number must be integer, got ${this.originalNumber}`);
    if(this.originalNumber > 0 && (this.originalNumber/this.maxNumber) >= 1) throw new Error(`Original number must be less than ${this.maxNumber}`);
    if(this.originalNumber < 0 && (this.originalNumber/this.maxNumber) <= -1) throw new Error(`Original number must be more than -${this.maxNumber}`);

    let _middleNumber = this.originalNumber;
    while(_middleNumber > 0) {
      this.value.push(_middleNumber%10);
      _middleNumber = parseInt(_middleNumber/10);
    }

    const lackOfNumberLength = NEW_NUM_MAX_LENGTH-this.value.length;
    if (lackOfNumberLength > 0) {
      for(let i=0; i<lackOfNumberLength; i++) {
        this.value.push(0);
      }
    }
  }
  getNumber() {
    // return this.value.reverse().reduce((a,b)=> a*10+b,0)
    return this.originalNumber;
  }
}

function saveAddUp(numberA, numberB) {
  if (numberA instanceof NewNumber && numberB instanceof NewNumber) {
    let result = [];
    for (let i = 0; i<NEW_NUM_MAX_LENGTH; i++) {
      result.push(numberA.value[i] + numberB.value[i]);
    }
    result = carry(result);
    check(result); // 檢查第最後一位是否 overflow
    
    // 總和後轉換成新的 number
    result = new NewNumber(result.reverse().reduce((a,b)=> a*10+b,0));
    return result;
  } else {
    throw new Error('Both of number A and number B must be NewNumber type');
  }
}

function carry(number) {
  const newNumber = [];
  for (let i=0; i<NEW_NUM_MAX_LENGTH; i++) {
    if (i<NEW_NUM_MAX_LENGTH-1) {
      // 只做到第三位, 因為第四位永遠不會進位, 如果有進位的 case, 留到 check 階段去排除
      const numberInThisDigit = number[i]%10;
      newNumber.push(numberInThisDigit);
      const numberAddToNextDigit = parseInt(number[i]/10);
      number[i+1] += numberAddToNextDigit;
    } else {
      const numberInThisDigit = number[i];
      newNumber.push(numberInThisDigit);
    }
  }
  return newNumber;
};

function check(number) {
  if (number[NEW_NUM_MAX_LENGTH-1]>=10) throw new Error('Add result will overflow');
}

function mean(numbersInList) {
  let result = new NewNumber(0);
  let remainder = 0;
  for (let i = 0; i<numbersInList.length; i++) {
    const newTestNumber = new NewNumber(numbersInList[i]);
    result = saveAddUp(result, newTestNumber);

    // 第二筆之後都需要除以 2
    if(i>0) {
      let tmpResult = [];
      for (let i = (result.value.length-1); i>=0; i-=1) {
        const digitResult = result.value[i]/2;
        tmpResult.push(parseInt(digitResult));

        if (digitResult>=1) {
          // 如果大於等於一, 取餘數後乗十加上下一位數
          if (i>0) {
            result.value[i-1] += (result.value[i]%2)*10;
          } else {
            remainder = (digitResult - parseInt(digitResult));
          }
        } else {
          // 如果小於一, 直接乗十加上下一位數
          if (i>0) {
            result.value[i-1] += result.value[i]*10;
          } else {
            remainder = (digitResult - parseInt(digitResult));
          }
        }
      }
      // 總和後轉換成新的 number
      result = new NewNumber(tmpResult.reduce((a,b)=> a*10+b,0));
    }
  }
  return result.getNumber()+remainder;
}

const numberList = [127, 64];
console.log(numberList);
const meanOfNumber = mean(numberList);
console.log(meanOfNumber);

```