Skip to content

Commit

Permalink
feature(#44): Support Arbitrary-Width Shifts, Add More Test Cases, Ad…
Browse files Browse the repository at this point in the history
…d Readme
  • Loading branch information
FlorianWendelborn committed Feb 18, 2021
1 parent e524183 commit 983d572
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 23 deletions.
28 changes: 27 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ or
## Table of Contents

- [bits](#bits)
- operations ([and](#bitsand), [nand](#bitsnand), [nor](#bitsnor), [not](#bitsnot), [or](#bitsor), [xnor](#bitsxnor), [xor](#bitsxor))
- operations ([and](#bitsand), [circularShiftLeft](#bitscircularshiftleft), [circularShiftRight](#bitscircularshiftright), [nand](#bitsnand), [nor](#bitsnor), [not](#bitsnot), [or](#bitsor), [xnor](#bitsxnor), [xor](#bitsxor))
- reduce operations ([reduceAnd](#bitsreduceand), [reduceNand](#bitsreducenand), [reduceNor](#bitsreducenor), [reduceOr](#bitsreduceor), [reduceXnor](#bitsreducexnor), [reduceXor](#bitsreducexor))
- [toString](#bitstostring)
- [buffer](#buffer)
Expand Down Expand Up @@ -104,6 +104,32 @@ bitwise.bits.and([1, 0, 0, 0, 1, 1, 0, 1], [0, 1, 1, 0, 0, 1, 0, 0])
// [0, 0, 0, 0, 0, 1, 0, 0]
```
### bits.circularShiftLeft
```ts
(bits1: Array<0|1>, amount: number): Array<0|1>
```
Applies the bitwise `LSHIFT` operation, expects two arrays of the same size and a shift amount and returns a new one.
```js
bitwise.bits.circularShiftLeft([0, 0, 0, 1, 1, 1, 1, 1], 1)
// [0, 0, 1, 1, 1, 1, 1, 0]
```
### bits.circularShiftRight
```ts
(bits1: Array<0|1>, amount: number): Array<0|1>
```
Applies the bitwise `RSHIFT` operation, expects two arrays of the same size and a shift amount and returns a new one.
```js
bitwise.bits.circularShiftRight([0, 0, 0, 1, 1, 1, 1, 1], 1)
// [1, 0, 0, 0, 1, 1, 1, 1]
```
### bits.nand
```ts
Expand Down
58 changes: 50 additions & 8 deletions source/bits/circular-shift-left.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,54 @@
import { Bits } from '../types'
import circularShiftLeft from './circular-shift-left'

test('CSHIFTL', () => {
const bits1: Bits = [1, 0, 0, 0, 1, 1, 0, 1]
const expected1: Bits = [0, 0, 0, 1, 1, 0, 1, 1]
expect(circularShiftLeft(bits1)).toEqual(expected1)

const bits2: Bits = [0, 0, 0, 1, 1, 1, 1, 1]
const expected2: Bits = [0, 0, 1, 1, 1, 1, 1, 0]
expect(circularShiftLeft(bits2)).toEqual(expected2)
test('circularShiftLeft with amount 1', () => {
const testCases: Array<[Bits, Bits]> = [
[
[1, 0, 0, 0, 1, 1, 0, 1],
[0, 0, 0, 1, 1, 0, 1, 1],
],
[
[0, 0, 0, 1, 1, 1, 1, 1],
[0, 0, 1, 1, 1, 1, 1, 0],
],
]

for (const [input, expectedResult] of testCases)
expect(circularShiftLeft(input, 1)).toEqual(expectedResult)
})

test('circularShiftLeft with amount 2', () => {
const testCases: Array<[Bits, Bits]> = [
[
[1, 0, 0, 0, 1, 1, 0, 1],
[0, 0, 1, 1, 0, 1, 1, 0],
],
[
[0, 0, 0, 1, 1, 1, 1, 1],
[0, 1, 1, 1, 1, 1, 0, 0],
],
]

for (const [input, expectedResult] of testCases)
expect(circularShiftLeft(input, 2)).toEqual(expectedResult)
})

test('circularShiftLeft with amount 3', () => {
const testCases: Array<[Bits, Bits]> = [
[
[1, 0, 0, 0, 1, 1, 0, 1],
[0, 1, 1, 0, 1, 1, 0, 0],
],
[
[0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 0, 0],
],
]

for (const [input, expectedResult] of testCases)
expect(circularShiftLeft(input, 3)).toEqual(expectedResult)
})

test('circularShiftLeft throws when amount too large', () => {
expect(() => circularShiftLeft([0, 1], 3)).toThrow()
})
12 changes: 9 additions & 3 deletions source/bits/circular-shift-left.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@ import { Bits } from '../types'
* @example
* circularShiftLeft([1,0,1,1,0,1]) => [0,1,1,0,1,1]
*
* @see {@link https://en.wikipedia.org/wiki/Circular_shift}
*
* @param {Array} bits input data
* @param {number} amount how far should it be shifted
* @return {Array} [CSHIFTL bits]
*/
export default (bits: Bits): Bits => {
export default (bits: Bits, amount: number): Bits => {
const result: Bits = []

for (let i: number = 1; i < bits.length; i++) result[i - 1] = bits[i]
result[bits.length - 1] = bits[0]
if (amount > bits.length)
throw new Error('shift amount can’t be larger than bits array length')

for (let i = 0; i < bits.length; i++)
result[(bits.length + i - amount) % bits.length] = bits[i]

return result
}
58 changes: 50 additions & 8 deletions source/bits/circular-shift-right.test.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,54 @@
import { Bits } from '../types'
import circularShiftRight from './circular-shift-right'

test('CSHIFTR', () => {
const bits1: Bits = [1, 0, 0, 0, 1, 1, 0, 1]
const expected1: Bits = [1, 1, 0, 0, 0, 1, 1, 0]
expect(circularShiftRight(bits1)).toEqual(expected1)

const bits2: Bits = [0, 0, 0, 1, 1, 1, 1, 1]
const expected2: Bits = [1, 0, 0, 0, 1, 1, 1, 1]
expect(circularShiftRight(bits2)).toEqual(expected2)
test('circularShiftRight with amount 1', () => {
const testCases: Array<[Bits, Bits]> = [
[
[1, 0, 0, 0, 1, 1, 0, 1],
[1, 1, 0, 0, 0, 1, 1, 0],
],
[
[0, 0, 0, 1, 1, 1, 1, 1],
[1, 0, 0, 0, 1, 1, 1, 1],
],
]

for (const [input, expectedResult] of testCases)
expect(circularShiftRight(input, 1)).toEqual(expectedResult)
})

test('circularShiftRight with amount 2', () => {
const testCases: Array<[Bits, Bits]> = [
[
[1, 0, 0, 0, 1, 1, 0, 1],
[0, 1, 1, 0, 0, 0, 1, 1],
],
[
[0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 0, 0, 0, 1, 1, 1],
],
]

for (const [input, expectedResult] of testCases)
expect(circularShiftRight(input, 2)).toEqual(expectedResult)
})

test('circularShiftRight with amount 3', () => {
const testCases: Array<[Bits, Bits]> = [
[
[1, 0, 0, 0, 1, 1, 0, 1],
[1, 0, 1, 1, 0, 0, 0, 1],
],
[
[0, 0, 0, 1, 1, 1, 1, 1],
[1, 1, 1, 0, 0, 0, 1, 1],
],
]

for (const [input, expectedResult] of testCases)
expect(circularShiftRight(input, 3)).toEqual(expectedResult)
})

test('circularShiftRight throws when amount too large', () => {
expect(() => circularShiftRight([0, 1], 3)).toThrow()
})
12 changes: 9 additions & 3 deletions source/bits/circular-shift-right.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,20 @@ import { Bit, Bits } from '../types'
* @example
* circularShiftRight([1,0,1,1,0,1]) => [1,1,0,1,1,0]
*
* @see {@link https://en.wikipedia.org/wiki/Circular_shift}
*
* @param {Array} bits input data
* @param {number} amount how far should it be shifted
* @return {Array} [CSHIFTR bits]
*/
export default (bits: Bits): Bits => {
export default (bits: Bits, amount: number): Bits => {
const result: Bits = []

result[0] = bits.pop() as Bit
for (let i: number = 0; i < bits.length; i++) result[i + 1] = bits[i]
if (amount > bits.length)
throw new Error('shift amount can’t be larger than bits array length')

for (let i = 0; i < bits.length; i++)
result[(i + amount) % bits.length] = bits[i]

return result
}

0 comments on commit 983d572

Please sign in to comment.