mirror of
https://github.com/josdejong/mathjs.git
synced 2026-01-25 15:07:57 +00:00
Implemented configuration value {number: 'fraction'}. Added docs and example for fractions.
This commit is contained in:
parent
a0ad13b9e0
commit
0c1e9deeeb
@ -3,6 +3,7 @@
|
||||
|
||||
## not yet released, version 2.0.0-SNAPSHOT
|
||||
|
||||
- Implemented support for fractions, powered by the library `fraction.js`.
|
||||
- Implemented matrix LU decomposition with partial pivoting and a LU based
|
||||
linear equations solver (functions `lup` and `lusolve`). Thanks @rjbaucells.
|
||||
- Large internal refactoring, allowing to create custom bundles of math.js.
|
||||
|
||||
@ -10,7 +10,7 @@ Powerful and easy to use.
|
||||
|
||||
## Features
|
||||
|
||||
- Supports numbers, big numbers, complex numbers, units, strings, arrays, and matrices.
|
||||
- Supports numbers, big numbers, complex numbers, fractions, units, strings, arrays, and matrices.
|
||||
- Is compatible with JavaScript's built-in Math library.
|
||||
- Contains a flexible expression parser.
|
||||
- Supports chained operations.
|
||||
|
||||
@ -24,12 +24,14 @@ The following configuration options are available:
|
||||
inputs, a matrix will be returned always.
|
||||
|
||||
- `number`. The default type of numbers. This setting is used by functions
|
||||
like `eval `which cannot determine the correct type of output from the
|
||||
like `eval` which cannot determine the correct type of output from the
|
||||
functions input. For most functions though, the type of output is determined
|
||||
from the the input: a number as input will return a number as output,
|
||||
a BigNumber as input returns a BigNumber as output.
|
||||
Available values are: `'number'` (default) or `'bignumber'`.
|
||||
BigNumbers have higher precision than the default numbers of JavaScript.
|
||||
Available values are: `'number'` (default), `'bignumber'`, or `'fraction'`.
|
||||
[BigNumbers](./datatypes/bignumbers.js) have higher precision than the default
|
||||
numbers of JavaScript, and [`Fractions`](./datatypes/fractions.js) store
|
||||
values in terms of a numerator and denominator.
|
||||
|
||||
- `precision`. The maximum number of significant digits for bigNumbers.
|
||||
This setting only applies to BigNumbers, not to numbers.
|
||||
@ -76,7 +78,7 @@ math2.range(0, 4); // Matrix [0, 1, 2, 3]
|
||||
|
||||
// create an instance of math.js with bignumber configuration
|
||||
var bigmath = math.create({
|
||||
number: 'bignumber', // Choose 'number' (default) or 'bignumber'
|
||||
number: 'bignumber', // Choose 'number' (default), 'bignumber', or 'fraction'
|
||||
precision: 32 // 64 by default, only applicable for BigNumbers
|
||||
});
|
||||
|
||||
@ -110,7 +112,7 @@ bigmath.eval('1 / 3'); // BigNumber, 0.33333333333333333333333333333333
|
||||
|
||||
// create a new instance of math.js with bignumber configuration
|
||||
var bigmath = math.create({
|
||||
number: 'bignumber', // Choose 'number' (default) or 'bignumber'
|
||||
number: 'bignumber', // Choose 'number' (default), 'bignumber', or 'fraction'
|
||||
precision: 32 // 64 by default, only applicable for BigNumbers
|
||||
});
|
||||
|
||||
|
||||
@ -21,7 +21,8 @@ BigNumbers instead of [numbers](numbers.md) by default, configure math.js like:
|
||||
|
||||
```js
|
||||
math.config({
|
||||
number: 'bignumber', // Default type of number: 'number' (default) or 'bignumber'
|
||||
number: 'bignumber', // Default type of number:
|
||||
// 'number' (default), 'bignumber', or 'fraction'
|
||||
precision: 64 // Number of significant digits for BigNumbers
|
||||
});
|
||||
|
||||
@ -83,21 +84,21 @@ console.log(ans.toString());
|
||||
## Conversion
|
||||
|
||||
BigNumbers can be converted to numbers and vice versa using the functions
|
||||
`number` and `bignumber`. When converting a BigNumber to a Number, the high
|
||||
`number` and `bignumber`. When converting a BigNumber to a number, the high
|
||||
precision of the BigNumber will be lost. When a BigNumber is too large to be represented
|
||||
as Number, it will be initialized as `Infinity`.
|
||||
|
||||
```js
|
||||
// converting numbers and BigNumbers
|
||||
var a = math.number(0.3); // Number, 0.3
|
||||
var a = math.number(0.3); // number, 0.3
|
||||
var b = math.bignumber(a); // BigNumber, 0.3
|
||||
var c = math.number(b); // Number, 0.3
|
||||
var c = math.number(b); // number, 0.3
|
||||
|
||||
// exceeding the maximum of a number
|
||||
var d = math.bignumber('1.2e500'); // BigNumber, 1.2e+500
|
||||
var e = math.number(d); // Number, Infinity
|
||||
var e = math.number(d); // number, Infinity
|
||||
|
||||
// loosing precision when converting to number
|
||||
var f = math.bignumber('0.2222222222222222222'); // BigNumber, 0.2222222222222222222
|
||||
var g = math.number(f); // Number, 0.2222222222222222
|
||||
var g = math.number(f); // number, 0.2222222222222222
|
||||
```
|
||||
|
||||
66
docs/datatypes/fractions.md
Normal file
66
docs/datatypes/fractions.md
Normal file
@ -0,0 +1,66 @@
|
||||
# Fractions
|
||||
|
||||
For calculations with fractions, math.js supports a `Fraction` data type.
|
||||
Fraction support is powered by [fraction.js](https://github.com/infusion/Fraction.js).
|
||||
Unlike [numbers](numbers.md) and [BigNumbers](./bignumbers.md), fractions can
|
||||
store numbers with infinitely repeating decimals, for example `1/3 = 0.3333333...`,
|
||||
which can be represented as `0.(3)`, or `2/7` which can be represented as `0.(285714)`.
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
A Fraction can be created using the function `fraction`:
|
||||
|
||||
```js
|
||||
math.fraction('1/3'); // Fraction, 0.(3)
|
||||
math.fraction(1, 3); // Fraction, 0.(3)
|
||||
math.fraction('0.(3)'); // Fraction, 0.(3)
|
||||
```
|
||||
|
||||
And can be used in functions like `add` and `multiply` like:
|
||||
|
||||
```js
|
||||
math.add(fraction('1/3'), fraction('1/6')); // Fraction, 0.5
|
||||
math.multiply(fraction('1/4'), fraction('1/2')); // Fraction, 0.125
|
||||
```
|
||||
|
||||
Note that not all functions support fractions. For example trigonometric
|
||||
functions doesn't support fractions. When not supported, the functions
|
||||
will convert the input to numbers and return a number as result.
|
||||
|
||||
Most functions will determine the type of output from the type of input:
|
||||
a number as input will return a number as output, a Fraction as input returns
|
||||
a Fraction as output. Functions which cannot determine the type of output
|
||||
from the input (for example `math.eval`) use the default number type `number`,
|
||||
which can be configured when instantiating math.js. To configure the use of
|
||||
fractions instead of [numbers](numbers.md) by default, configure math.js like:
|
||||
|
||||
```js
|
||||
// Configure the default type of number: 'number' (default), 'bignumber', or 'fraction'
|
||||
math.config({
|
||||
number: 'fraction'
|
||||
});
|
||||
|
||||
// use math
|
||||
math.eval('0.1 + 0.2'); // Fraction, 0.3
|
||||
```
|
||||
|
||||
|
||||
## Conversion
|
||||
|
||||
Fractions can be converted to numbers and vice versa using the functions
|
||||
`number` and `fraction`. When converting a Fraction to a number, precision
|
||||
may be lost when the value cannot represented in 16 digits.
|
||||
|
||||
```js
|
||||
// converting numbers and fractions
|
||||
var a = math.number(0.3); // number, 0.3
|
||||
var b = math.fraction(a); // Fraction, 0.3
|
||||
var c = math.number(b); // number, 0.3
|
||||
|
||||
// loosing precision when converting to number: a fraction can represent
|
||||
// a number with an infinite number of repeating decimals, a number just
|
||||
// stores about 16 digits and cuts consecutive digits.
|
||||
var d = math.fraction('1/3'); // Fraction, 0.(3)
|
||||
var e = math.number(f); // number, 0.3333333333333333
|
||||
```
|
||||
@ -11,6 +11,7 @@ The supported data types are:
|
||||
- [Number](numbers.md)
|
||||
- [BigNumber](bignumbers.md)
|
||||
- [Complex](complex_numbers.md)
|
||||
- [Fraction](fractions.md)
|
||||
- [Array](matrices.md)
|
||||
- [Matrix](matrices.md)
|
||||
- [Unit](units.md)
|
||||
@ -27,6 +28,9 @@ math.sqrt(4.41e2); // 21
|
||||
// use BigNumbers
|
||||
math.add(math.bignumber(0.1), math.bignumber(0.2)); // BigNumber, 0.3
|
||||
|
||||
// use Fractions
|
||||
math.add(math.fraction(1), math.fraction(3)); // Fraction, 0.(3)
|
||||
|
||||
// use strings
|
||||
math.add('hello ', 'world'); // 'hello world'
|
||||
math.max('A', 'D', 'C'); // 'D'
|
||||
|
||||
@ -16,7 +16,8 @@ can be configured when instantiating math.js:
|
||||
|
||||
```js
|
||||
math.config({
|
||||
number: 'number' // Default type of number: 'number' (default) or 'bignumber'
|
||||
number: 'number' // Default type of number:
|
||||
// 'number' (default), 'bignumber', or 'fraction'
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
@ -272,7 +272,7 @@ The default number type of the expression parser can be changed at instantiation
|
||||
of math.js. The expression parser parses numbers as BigNumber by default:
|
||||
|
||||
```js
|
||||
// Configure the type of number: 'number' (default) or 'bignumber'
|
||||
// Configure the type of number: 'number' (default), 'bignumber', or 'fraction'
|
||||
math.config({number: 'bignumber'});
|
||||
|
||||
// all numbers are parsed as BigNumber
|
||||
|
||||
@ -5,18 +5,11 @@ var math = require('../index');
|
||||
|
||||
// configure the default type of numbers as BigNumbers
|
||||
math.config({
|
||||
number: 'bignumber', // Default type of number: 'number' (default) or 'bignumber'
|
||||
number: 'bignumber', // Default type of number:
|
||||
// 'number' (default), 'bignumber', or 'fraction'
|
||||
precision: 20 // Number of significant digits for BigNumbers
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper function to output a value in the console. Value will be formatted.
|
||||
* @param {*} value
|
||||
*/
|
||||
function print (value) {
|
||||
console.log(math.format(value));
|
||||
}
|
||||
|
||||
console.log('round-off errors with numbers');
|
||||
print(math.add(0.1, 0.2)); // Number, 0.30000000000000004
|
||||
print(math.divide(0.3, 0.2)); // Number, 1.4999999999999998
|
||||
@ -38,3 +31,11 @@ console.log('use BigNumbers in the expression parser');
|
||||
print(math.eval('0.1 + 0.2')); // BigNumber, 0.3
|
||||
print(math.eval('0.3 / 0.2')); // BigNumber, 1.5
|
||||
console.log();
|
||||
|
||||
/**
|
||||
* Helper function to output a value in the console. Value will be formatted.
|
||||
* @param {*} value
|
||||
*/
|
||||
function print (value) {
|
||||
console.log(math.format(value));
|
||||
}
|
||||
|
||||
42
examples/fractions.js
Normal file
42
examples/fractions.js
Normal file
@ -0,0 +1,42 @@
|
||||
// Fractions
|
||||
|
||||
// load math.js
|
||||
var math = require('../index');
|
||||
|
||||
// configure the default type of numbers as Fractions
|
||||
math.config({
|
||||
number: 'fraction' // Default type of number:
|
||||
// 'number' (default), 'bignumber', or 'fraction'
|
||||
});
|
||||
|
||||
console.log('round-off errors with numbers');
|
||||
print(math.add(0.1, 0.2)); // Number, 0.30000000000000004
|
||||
print(math.divide(0.3, 0.2)); // Number, 1.4999999999999998
|
||||
console.log();
|
||||
|
||||
console.log('no round-off errors with Fractions');
|
||||
print(math.add(math.fraction(0.1), math.fraction(0.2))); // Fraction, 0.3
|
||||
print(math.divide(math.fraction(0.3), math.fraction(0.2))); // Fraction, 1.5
|
||||
console.log();
|
||||
|
||||
console.log('Represent an infinite number of repeating digits');
|
||||
print(math.fraction('1/3')); // Fraction, 0.(3)
|
||||
print(math.fraction('2/7')); // Fraction, 0.(285714)
|
||||
print(math.fraction('23/11')); // Fraction, 2.(09)
|
||||
console.log();
|
||||
|
||||
// one can work conveniently with fractions using the expression parser.
|
||||
// note though that Fractions are only supported by basic arithmetic functions
|
||||
console.log('use fractions in the expression parser');
|
||||
print(math.eval('0.1 + 0.2')); // Fraction, 0.3
|
||||
print(math.eval('0.3 / 0.2')); // Fraction, 1.5
|
||||
print(math.eval('23 / 11')); // Fraction, 2.(09)
|
||||
console.log();
|
||||
|
||||
/**
|
||||
* Helper function to output a value in the console. Value will be formatted.
|
||||
* @param {*} value
|
||||
*/
|
||||
function print (value) {
|
||||
console.log(math.format(value));
|
||||
}
|
||||
@ -87,9 +87,14 @@ function factory (type, config, load, typed) {
|
||||
ConstantNode.prototype._compile = function (defs) {
|
||||
switch (this.valueType) {
|
||||
case 'number':
|
||||
if (defs.math.config().number === 'bignumber') {
|
||||
// TODO: replace this with using config.number
|
||||
var numConfig = defs.math.config().number;
|
||||
if (numConfig === 'bignumber') {
|
||||
return 'math.bignumber("' + this.value + '")';
|
||||
}
|
||||
else if (numConfig === 'fraction') {
|
||||
return 'math.fraction("' + this.value + '")';
|
||||
}
|
||||
else {
|
||||
// remove leading zeros like '003.2' which are not allowed by JavaScript
|
||||
return this.value.replace(/^(0*)[0-9]/, function (match, zeros) {
|
||||
|
||||
@ -203,6 +203,20 @@ describe('parse', function() {
|
||||
|
||||
});
|
||||
|
||||
describe('fraction', function () {
|
||||
|
||||
it('should output fractions if default number type is fraction', function() {
|
||||
var fmath = math.create({
|
||||
number: 'fraction'
|
||||
});
|
||||
|
||||
assert(parse('0.1').compile(fmath).eval() instanceof math.type.Fraction);
|
||||
assert.equal(parse('1/3').compile(fmath).eval().toString(), '0.(3)');
|
||||
assert.equal(parse('0.1+0.2').compile(fmath).eval().toString(), '0.3');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('string', function () {
|
||||
|
||||
it('should parse a string', function() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user