Skip to content

Commit

Permalink
Merge pull request #49 from FlorianWendelborn/0xflotus-circular-shift
Browse files Browse the repository at this point in the history
feature(#44): Add Circular Shift
  • Loading branch information
FlorianWendelborn authored Feb 18, 2021
2 parents a9337b8 + d97e42a commit 59c5e56
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 1 deletion.
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
(bits: Array<0|1>, amount: number): Array<0|1>
```
Applies the bitwise `ROL` 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
(bits: Array<0|1>, amount: number): Array<0|1>
```
Applies the bitwise `ROR` 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
54 changes: 54 additions & 0 deletions source/bits/circular-shift-left.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Bits } from '../types'
import circularShiftLeft from './circular-shift-left'

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()
})
25 changes: 25 additions & 0 deletions source/bits/circular-shift-left.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Bits } from '../types'

/**
* Circular Shift Left
*
* @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} [ROL bits]
*/
export default (bits: Bits, amount: number): Bits => {
const result: Bits = []

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
}
54 changes: 54 additions & 0 deletions source/bits/circular-shift-right.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Bits } from '../types'
import circularShiftRight from './circular-shift-right'

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()
})
25 changes: 25 additions & 0 deletions source/bits/circular-shift-right.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Bits } from '../types'

/**
* Circular Shift Right
*
* @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} [ROR bits]
*/
export default (bits: Bits, amount: number): Bits => {
const result: Bits = []

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
}
6 changes: 6 additions & 0 deletions source/bits/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import and from './and'
import circularShiftLeft from './circular-shift-left'
import circularShiftRight from './circular-shift-right'
import nand from './nand'
import nor from './nor'
import not from './not'
Expand All @@ -16,6 +18,8 @@ import xor from './xor'

export {
and,
circularShiftLeft,
circularShiftRight,
nand,
nor,
not,
Expand All @@ -34,6 +38,8 @@ export {

export default {
and,
circularShiftLeft,
circularShiftRight,
nand,
nor,
not,
Expand Down

0 comments on commit 59c5e56

Please sign in to comment.