{
- "stage": 0
-}
\ No newline at end of file
+ "optional": [
+ "es7.asyncFunctions",
+ "es7.classProperties",
+ "es7.decorators",
+ "es7.objectRestSpread"
+ ]
+}
--- /dev/null
+/**
+ * Copyright 2015-present Greg Hurrell. All rights reserved.
+ * Licensed under the terms of the MIT license.
+ */
+
+'use strict';
+
+import multiplyDigits from '../multiplyDigits';
+
+describe('multiplyDigits()', () => {
+ it('multiplies by 0', () => {
+ expect(multiplyDigits([1], 0, 2)).toEqual([0]);
+ expect(multiplyDigits([5], 0, 8)).toEqual([0]);
+ expect(multiplyDigits([4], 0, 10)).toEqual([0]);
+ expect(multiplyDigits([12], 0, 16)).toEqual([0]);
+ });
+
+ it('multiplies by 1', () => {
+ expect(multiplyDigits([1], 1, 2)).toEqual([1]);
+ expect(multiplyDigits([5], 1, 8)).toEqual([5]);
+ expect(multiplyDigits([4], 1, 10)).toEqual([4]);
+ expect(multiplyDigits([12], 1, 16)).toEqual([12]);
+ });
+
+ it('multiplies by 2', () => {
+ expect(multiplyDigits([1], 2, 2)).toEqual([0, 1]);
+ expect(multiplyDigits([5], 2, 8)).toEqual([2, 1]);
+ expect(multiplyDigits([4], 2, 10)).toEqual([8]);
+ expect(multiplyDigits([12], 2, 16)).toEqual([8, 1]);
+ });
+
+ it('multiplies by 100', () => {
+ expect(multiplyDigits([1], 100, 2)).toEqual([0, 0, 1, 0, 0, 1, 1]);
+ expect(multiplyDigits([5], 100, 8)).toEqual([4, 6, 7]);
+ expect(multiplyDigits([4], 100, 10)).toEqual([0, 0, 4]);
+ expect(multiplyDigits([12], 100, 16)).toEqual([0, 11, 4]);
+ });
+});
'use strict';
-/**
- * Strips the leading prefix from `number` in `base` and returns the remaining
- * part of the string.
- *
- * - "0x" (or "0X") for hexadecimal numbers.
- * - "0" for octal numbers.
- *
- * For all bases, leading whitespace is stripped.
- */
-function stripPrefix(number: string, base: number): string {
- if (base === 16) {
- return number.replace(/^\s*0x/i, '');
- } else if (base === 8) {
- return number.replace(/^\s*0/, '');
- } else {
- return number.replace(/^\s*/, '');
- }
-}
-
-/**
- * Breaks the string repsentation of `number` in `base` into an array of decimal
- * digits (from least significant to most significant) for easier manipulation.
- *
- * For example, the hexadecimal representation `"40fa"` becomes `[10, 15, 0,
- * 4]`.
- */
-function getDigits(number: string, base: number): Array<number> {
- return stripPrefix(number, base).trim().split('').reverse().map(digit => {
- const result = parseInt(digit, base);
- if (isNaN(result)) {
- throw new Error('Invalid digit `' + digit + '` for base `' + base + '`');
- }
- return result;
- });
-}
+import addDigits from './addDigits';
+import getDigits from './getDigits';
/**
* Adds two numbers `a` and `b`, both in `base` and returns the answer as a
export default function add(a: string, b: string, base: number): string {
const aDigits = getDigits(a, base);
const bDigits = getDigits(b, base);
- let result = '';
- let carry = 0;
- for (
- let i = 0, max = Math.max(aDigits.length, bDigits.length);
- i < max || carry;
- i++
- ) {
- const aDigit = aDigits[i] || 0;
- const bDigit = bDigits[i] || 0;
- const sum = aDigit + bDigit + carry;
- result = (sum % base).toString(base) + result;
- carry = Math.floor(sum / base);
- }
- return result ? result : '0';
+ return addDigits(aDigits, bDigits, base)
+ .reverse()
+ .map(number => number.toString(base))
+ .join('');
}
--- /dev/null
+/**
+ * Copyright 2015-present Greg Hurrell. All rights reserved.
+ * Licensed under the terms of the MIT license.
+ *
+ * @flow
+ */
+
+'use strict';
+
+export default function addDigits(
+ aDigits: Array<number>,
+ bDigits: Array<number>,
+ base: number
+): Array<number> {
+ let result = [];
+ let carry = 0;
+ for (
+ let i = 0, max = Math.max(aDigits.length, bDigits.length);
+ i < max || carry;
+ i++
+ ) {
+ const aDigit = aDigits[i] || 0;
+ const bDigit = bDigits[i] || 0;
+ const sum = aDigit + bDigit + carry;
+ result.push(sum % base);
+ carry = Math.floor(sum / base);
+ }
+ return result.length ? result : [0];
+}
--- /dev/null
+/**
+ * Copyright 2015-present Greg Hurrell. All rights reserved.
+ * Licensed under the terms of the MIT license.
+ *
+ * @flow
+ */
+
+'use strict';
+
+/**
+ * Strips the leading prefix from `number` in `base` and returns the remaining
+ * part of the string.
+ *
+ * - "0x" (or "0X") for hexadecimal numbers.
+ * - "0" for octal numbers.
+ *
+ * For all bases, leading whitespace is stripped.
+ */
+function stripPrefix(number: string, base: number): string {
+ if (base === 16) {
+ return number.replace(/^\s*0x/i, '');
+ } else if (base === 8) {
+ return number.replace(/^\s*0/, '');
+ } else {
+ return number.replace(/^\s*/, '');
+ }
+}
+
+/**
+ * Breaks the string repsentation of `number` in `base` into an array of decimal
+ * digits (from least significant to most significant) for easier manipulation.
+ *
+ * For example, the hexadecimal representation `"40fa"` becomes `[10, 15, 0,
+ * 4]`.
+ */
+export default function getDigits(number: string, base: number): Array<number> {
+ return stripPrefix(number, base).trim().split('').reverse().map(digit => {
+ const result = parseInt(digit, base);
+ if (isNaN(result)) {
+ throw new Error('Invalid digit `' + digit + '` for base `' + base + '`');
+ }
+ return result;
+ });
+}
--- /dev/null
+/**
+ * Copyright 2015-present Greg Hurrell. All rights reserved.
+ * Licensed under the terms of the MIT license.
+ *
+ * @flow
+ */
+
+'use strict';
+
+import addDigits from './addDigits';
+
+/**
+ * Multiplication is repeated addition.
+ */
+export default function multiplyDigits(
+ multiplicand: Array<number>,
+ multiplier: number,
+ base: number
+): Array<number> {
+ let result = [0];
+ for (let i = 0; i < multiplier; i++) {
+ result = addDigits(result, multiplicand, base);
+ }
+ return result;
+}