Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/develop' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
josdejong committed Apr 3, 2023
2 parents c5b07c8 + db3e62e commit d9cf344
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 10 deletions.
20 changes: 20 additions & 0 deletions docs/datatypes/units.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,26 @@ math.createUnit('θ', '1 rad')
math.evaluate('1θ + 3 deg').toNumber('deg') // 60.29577951308232
```

## Numeric type of the value of a unit

The built-in units are always created with a value being a `number`. To turn the value into for example a `BigNumber` or `Fraction`, you can convert the value using the function `math.fraction` and `math.bignumber`:

```js
math.unit(math.fraction(10), 'inch').toNumeric('cm') // Fraction 127/5
math.fraction(math.unit(10, 'inch')).toNumeric('cm') // Fraction 127/5

math.bignumber(math.unit(10, 'inch')).toNumeric('cm') // BigNumber 25.4
math.unit(math.bignumber(10), 'inch').toNumeric('cm') // BigNumber 25.4
```

When using the expression parser, it is possible to configure numeric values to be parsed as `Fraction` or `BigNumber`:

```js
math.config({ number: 'Fraction' })
math.evaluate('10 inch').toNumeric('cm') // Fraction 127/5
```


## API
A `Unit` object contains the following functions:

Expand Down
6 changes: 6 additions & 0 deletions src/type/bignumber/function/bignumber.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ export const createBignumber = /* #__PURE__ */ factory(name, dependencies, ({ ty
return x
},

Unit: typed.referToSelf(self => (x) => {
const clone = x.clone()
clone.value = self(x.value)
return clone
}),

Fraction: function (x) {
return new BigNumber(x.n).div(x.d).times(x.s)
},
Expand Down
8 changes: 7 additions & 1 deletion src/type/fraction/function/fraction.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const createFraction = /* #__PURE__ */ factory(name, dependencies, ({ typ
*
* bignumber, number, string, unit
*
* @param {number | string | Fraction | BigNumber | Array | Matrix} [args]
* @param {number | string | Fraction | BigNumber | Unit | Array | Matrix} [args]
* Arguments specifying the value, or numerator and denominator of
* the fraction
* @return {Fraction | Array | Matrix} Returns a fraction
Expand Down Expand Up @@ -71,6 +71,12 @@ export const createFraction = /* #__PURE__ */ factory(name, dependencies, ({ typ
return x // fractions are immutable
},

Unit: typed.referToSelf(self => (x) => {
const clone = x.clone()
clone.value = self(x.value)
return clone
}),

Object: function (x) {
return new Fraction(x)
},
Expand Down
8 changes: 5 additions & 3 deletions src/type/number.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,11 @@ export const createNumber = /* #__PURE__ */ factory(name, dependencies, ({ typed
return x.valueOf()
},

Unit: function (x) {
throw new Error('Second argument with valueless unit expected')
},
Unit: typed.referToSelf(self => (x) => {
const clone = x.clone()
clone.value = self(x.value)
return clone
}),

null: function (x) {
return 0
Expand Down
14 changes: 14 additions & 0 deletions test/unit-tests/type/bignumber/function/bignumber.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,20 @@ describe('bignumber', function () {
assert.strictEqual(b.toString(), '0.6666666666666666666666666666666666666666666666666666666666666667')
})

it('should convert the number value of a Unit to BigNumber', function () {
const b = math.bignumber(math.unit(10, 'inch')).toNumeric('cm')

assert.ok(b instanceof BigNumber)
assert.strictEqual(b.valueOf(), '25.4')
})

it('should convert the Fraction value of a Unit to BigNumber', function () {
const b = math.bignumber(math.unit(math.fraction(1, 2), 'cm')).toNumeric('cm')

assert.ok(b instanceof BigNumber)
assert.strictEqual(b.valueOf(), '0.5')
})

it('should apply precision setting to bignumbers', function () {
const mymath = math.create({
precision: 32
Expand Down
14 changes: 14 additions & 0 deletions test/unit-tests/type/fraction/function/fraction.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ describe('fraction', function () {
equalFraction(math.fraction(null), new Fraction(0))
})

it('should create a fraction from an irrational number', function () {
equalFraction(math.fraction(math.pi), new Fraction(11985110, 3814979))
})

it('should fail to create a fraction in case of non-integer quotient', function () {
assert.throws(() => math.fraction(4, 5.1), /Parameters must be integer/)
assert.throws(() => math.fraction(62.8, 10), /Parameters must be integer/)
Expand All @@ -28,6 +32,16 @@ describe('fraction', function () {
equalFraction(f, new Fraction('0.6666666666666666666666666666666666666666666666666666666666666667'))
})

it('should convert the number value of a Unit to Fraction', function () {
equalFraction(math.fraction(math.unit(0.5, 'cm')).toNumeric('cm'), new Fraction(1, 2))
equalFraction(math.fraction(math.unit(10, 'inch')).toNumeric('cm'), new Fraction(127, 5))
})

it('should convert the BigNumber value of a Unit to Fraction', function () {
equalFraction(math.fraction(math.unit(math.bignumber(0.5), 'cm')).toNumeric('cm'), new Fraction(1, 2))
equalFraction(math.fraction(math.unit(math.bignumber(10), 'inch')).toNumeric('cm'), new Fraction(127, 5))
})

it('should clone a fraction', function () {
const a = math.fraction(1, 3)
const b = math.fraction(a)
Expand Down
6 changes: 5 additions & 1 deletion test/unit-tests/type/number.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ describe('number', function () {
approx.equal(number(math.unit('52cm'), 'm'), 0.52)
})

it('should convert the value of a unit to a number', function () {
const value = number(math.unit(math.bignumber(52), 'cm'))
assert.strictEqual(value.toNumeric('cm'), 52)
})

it('should parse the string if called with a valid string', function () {
approx.equal(number('2.1e3'), 2100)
approx.equal(number(' 2.1e-3 '), 0.0021)
Expand Down Expand Up @@ -64,7 +69,6 @@ describe('number', function () {
})

it('should throw an error with wrong type of arguments', function () {
assert.throws(function () { number(math.unit('5cm')) }, /Second argument with valueless unit expected/)
// assert.throws(function () {number(math.unit('5cm'), 2)}, TypeError); // FIXME: this should also throw an error
assert.throws(function () { number(math.unit('5cm'), new Date()) }, TypeError)
assert.throws(function () { number('23', 2) }, TypeError)
Expand Down
10 changes: 5 additions & 5 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ declare namespace math {
* @returns The created bignumber
*/
bignumber(
x?: number | string | Fraction | BigNumber | boolean | Fraction | null
x?: number | string | Fraction | BigNumber | Unit | boolean | null
): BigNumber
bignumber<T extends MathCollection>(x: T): T

Expand Down Expand Up @@ -664,12 +664,12 @@ declare namespace math {

/**
* Create a fraction convert a value to a fraction.
* @param args Arguments specifying the numerator and denominator of the
* @param value Arguments specifying the numerator and denominator of the
* fraction
* @returns Returns a fraction
*/
fraction(
value: number | string | BigNumber | Fraction | FractionDefinition
value: number | string | BigNumber | Unit | Fraction | FractionDefinition
): Fraction
fraction(values: MathCollection): MathCollection
/**
Expand Down Expand Up @@ -4148,7 +4148,7 @@ declare namespace math {
*/
bignumber(
this: MathJsChain<
number | string | Fraction | BigNumber | boolean | Fraction | null
number | string | Fraction | BigNumber | Unit | boolean | null
>
): MathJsChain<BigNumber>
bignumber<T extends MathCollection>(this: MathJsChain<T>): MathJsChain<T>
Expand Down Expand Up @@ -4214,7 +4214,7 @@ declare namespace math {
*/
fraction(
this: MathJsChain<
number | string | BigNumber | Fraction | FractionDefinition
number | string | BigNumber | Unit | Fraction | FractionDefinition
>,
denominator?: number
): MathJsChain<Fraction>
Expand Down

0 comments on commit d9cf344

Please sign in to comment.