1
\$\begingroup\$

I've got to made a function which returns the checksum of an given integer.

Source code of my implementation so far:

function computeChecksum(num) {
  if (typeof num !== 'number' || isNaN(num)) {
    throw new Error('Number, which is not NaN, expected as Parameter.');
  }

  num = Math.floor(Math.abs(num)); // Make sure the computation is done based upon an positive Integer.

  if (num < 10) {
    return num;
  }

  let divisor = Math.pow(10, num.toString().length);
  let checksum = 0;

  while (divisor >= 10) {
    let quotient = Math.floor(num / divisor);
    let divisorAsString = divisor.toString(); // For avoiding calling .toString() two times later. Appropriated or exaggeration?

    checksum += quotient;
    num -= quotient * divisor;
    
    // Should I pass the return-value of .slice() through parseInt()?
    //  Or just keep the implicit casting which is done when using it as an arithmetic operand?
    divisor = divisorAsString.slice(0, divisorAsString.length - 1);
  }

  return checksum + num;
}

// -------- Just testing & demo-usage------------------
// -- Not important concerning question ! -------------
let testNumbers = [11, 111, 1111,
  1111, 11111, 111111,
  123, 468, 2510,
  2501, 123456789, 1
];
let biggestSize = Math.max.apply(null, testNumbers);
let pad = new Array(biggestSize.toString().length);

pad = pad.join(' ');

testNumbers.forEach((num) => {
  console.log('%s > %s',
    (pad + num).slice(-pad.length),
    computeChecksum(num));
});
// ----------------------------------------------------

Because not in a special hurry I've avoided to search the internet for other (already available) solutions.

So the code above is the solution which came to my mind. It seems to work as expected. Please see the added testing.

Nevertheless I like to ask:

  • Are there a better algorithm for computing a checksum in JavaScript?

  • Could parts of my implementation been improved by using other patterns? For example the pattern I used for creating an integer with a defined size. Perhaps there's a better way?

Two further questions I've put right into my code as comments. I think that way it is better understandable what I mean.

All comments, recommendations and hints concerning my question (and my code in general) appreciated.

\$\endgroup\$
1
\$\begingroup\$

Your approach is far too complicated.

How about just

function computeChecksum(num) {
  if (typeof num !== 'number' || isNaN(num)) {
    throw new Error('Number, which is not NaN, expected as Parameter.');
  }

  num = Math.floor(Math.abs(num));

  const sum = num.toString().split('').reduce(
                                  (acc, val) => acc + parseInt(val),
                                  0);
  return sum;
}

Or instead of converting between string and number you can use modulo:

function computeChecksum(num) {
  if (typeof num !== 'number' || isNaN(num)) {
    throw new Error('Number, which is not NaN, expected as Parameter.');
  }

  num = Math.floor(Math.abs(num));

  let checksum = 0;

  while (num > 0) {
    checksum += num % 10;
    num = Math.floor(num / 10);
  }

  return checksum;
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.