Skip to content

Commit

Permalink
Number: add remainder
Browse files Browse the repository at this point in the history
  • Loading branch information
gcanti committed Feb 8, 2023
1 parent cf4918d commit 549509b
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/six-otters-cover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@fp-ts/core": patch
---

Number: add remainder
25 changes: 25 additions & 0 deletions docs/modules/Number.ts.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ Added in v1.0.0
- [divide](#divide)
- [multiply](#multiply)
- [multiplyAll](#multiplyall)
- [remainder](#remainder)
- [subtract](#subtract)
- [sum](#sum)
- [sumAll](#sumall)
Expand Down Expand Up @@ -94,6 +95,30 @@ export declare const multiplyAll: (collection: Iterable<number>) => number
Added in v1.0.0
## remainder
Returns the remainder left over when one operand is divided by a second operand.
It always takes the sign of the dividend.
**Signature**
```ts
export declare const remainder: { (divisor: number): (self: number) => number; (self: number, divisor: number): number }
```
**Example**
```ts
import { remainder } from '@fp-ts/core/Number'

assert.deepStrictEqual(remainder(2, 2), 0)
assert.deepStrictEqual(remainder(3, 2), 1)
assert.deepStrictEqual(remainder(-4, 2), -0)
```

Added in v1.0.0

## subtract

**Signature**
Expand Down
31 changes: 31 additions & 0 deletions src/Number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,37 @@ export const sumAll: (collection: Iterable<number>) => number = MonoidSum.combin
*/
export const multiplyAll: (collection: Iterable<number>) => number = MonoidMultiply.combineAll

/**
* Returns the remainder left over when one operand is divided by a second operand.
*
* It always takes the sign of the dividend.
*
* @param self - The dividend.
* @param divisor - The divisor.
*
* @example
* import { remainder } from "@fp-ts/core/Number"
*
* assert.deepStrictEqual(remainder(2, 2), 0)
* assert.deepStrictEqual(remainder(3, 2), 1)
* assert.deepStrictEqual(remainder(-4, 2), -0)
*
* @category algebraic operations
* @since 1.0.0
*/
export const remainder: {
(divisor: number): (self: number) => number
(self: number, divisor: number): number
} = dual(2, (self: number, divisor: number): number => {
// https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034
const valDecCount = (self.toString().split(".")[1] || "").length
const stepDecCount = (divisor.toString().split(".")[1] || "").length
const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount
const valInt = parseInt(self.toFixed(decCount).replace(".", ""))
const stepInt = parseInt(divisor.toFixed(decCount).replace(".", ""))
return (valInt % stepInt) / Math.pow(10, decCount)
})

/*
Missing:
Expand Down
16 changes: 16 additions & 0 deletions test/Number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,20 @@ describe.concurrent("Number", () => {
deepStrictEqual(Number.sign(10), 1)
deepStrictEqual(Number.sign(0.1), 1)
})

it("remainder", () => {
assert.deepStrictEqual(Number.remainder(2, 2), 0)
assert.deepStrictEqual(Number.remainder(3, 2), 1)
assert.deepStrictEqual(Number.remainder(4, 2), 0)
assert.deepStrictEqual(Number.remainder(-2, 2), -0)
assert.deepStrictEqual(Number.remainder(-3, 2), -1)
assert.deepStrictEqual(Number.remainder(-4, 2), -0)
assert.deepStrictEqual(Number.remainder(-2.8, -.2), -0)
assert.deepStrictEqual(Number.remainder(-2, -.2), -0)
assert.deepStrictEqual(Number.remainder(-1.5, -.2), -0.1)
assert.deepStrictEqual(Number.remainder(0, -.2), 0)
assert.deepStrictEqual(Number.remainder(1, -.2), 0)
assert.deepStrictEqual(Number.remainder(2.6, -.2), 0)
assert.deepStrictEqual(Number.remainder(3.1, -.2), 0.1)
})
})

0 comments on commit 549509b

Please sign in to comment.