mikemcl / big.js Goto Github PK
View Code? Open in Web Editor NEWA small, fast JavaScript library for arbitrary-precision decimal arithmetic.
Home Page: http://mikemcl.github.io/big.js
License: MIT License
A small, fast JavaScript library for arbitrary-precision decimal arithmetic.
Home Page: http://mikemcl.github.io/big.js
License: MIT License
I don't understand why they are different. Is this a rounding bug?
var big = require('big.js')
undefined
big(5757176871).times(34739248850845319).toString()
'2.0000000000000000510259372e+26'
big(5757176871).times('34739248850845319').toString()
'1.99999999999999999345416849e+26'
Thanks for this fantastic library! We needed it to solve floating point issues and have been using it to great success.
We have an issue:
var periodic = Big(80).div(3);
console.log('Big: ', periodic.toString());
console.log('Number: ', Number(periodic));
This will output:
Big: 26.66666666666666666667
Number: 26.666666666666668
What is going on with that 8 at the end? How can I have the number report correctly? What am I missing or not understanding properly?
Thanks in advance for any input.
Best regards,
Rafa.
I'd like to be able to set the rounding mode of a specific Big instance only. It seems that this is currently not possible?
I have test case like this:
var t1 = “143.50”;
var t2 = “143.10”;
var n1 = new Number(t1);
var n2 = new Number(t2);
var a= new Big((n1-n2).toFixed(3));
var b= new Big(t1-t2);
var c= a.round(2,3);
var d= b.round(2,3);
the result output like this:
a=0.4
b=0.4000000000000057
c=0.4
d=0.41
so, result of "c" is my expected result, but we must “toFixed(3)" befor "round(2,3)".
could you tell me how could I calculate "0.4" more sample?
I'm doing some math with discount percentages and amounts in a retail setting. I'd like to store the discount percentage and amount as a raw number in the database. It seems like the best way (using Big) is to do the math then use toFixed
with parseFloat
.
# MathLib is Big.js
fullPrice = MathLib(p.price).times(t.qty)
tTotal = fullPrice.times(MathLib(1).minus(discount))
fullPrice = parseFloat(fullPrice.toFixed(2))
tTotal = parseFloat(tTotal.toFixed(2))
Is parseFloat with toFixed the best way to go here? I think it'd be helpful to wrap this method (whatever the best form is) into a .toNumber
function. Give me some direction here and I'll make a PR for it.
var Big = require('big.js');
var n = new Big('534.45');
console.log(n instanceof Big);
This works mostly: in browser and node. But breaks in tests. Apparently instanceof
isn't very reliable.
It would be great, if one could console.log(Big.isBig(n));
I am using the library and it is very cool!
I notice that many times it is more natural for the people to enter values < 0 in the format .45
, without the leading zero (not 0.45
).
But the library throws an exception in this case
var a = Big(".45"); // exception 'NaN'
.
Maybe inside the Big constructor:
if (n[0] === ".") { n = "0" + n; }
if (n[n.length - 1] === ".") { n = n + "0"; } // or chop the last "."
Thank you.
The test folder is about 3.0
MB, but is not needed in the npm package, so it would be good to exclude this folder from the npm package.
Can you explain the differences between bignumber.js and big.js? Thanks!
I have noticed that e.g. the documentation explicitly says that the coefficient is single digits (base 10). For my use case, big.js's small size is great, but I'd also like the performance of bigdecimal.js. Is changing the internal base an option?
(Thanks for a great library!)
When I run the following code,
new Big(-0.4).round(0).toString()
I get a string value of 0
and I was expecting -0
.
The tests seem to suggest that you would expect that too.
T(-0, -0.4);
Although, String(-0) will give 0
and so 0
=== '0' -> pass.
But I wonder if you really meant?
T('-0', -0.4);
Which would give 0
=== '-0̈́` -> fail.
I was hoping that you could clarify the situation?
Based on big.js documentation, with x
only, not y
and z
:
x = new Big('177.7e+457')
str = JSON.stringify( [x] )
JSON.parse( str, function ( k, v ) { return k === '' ? v : new Big(v) } )
// Returns an array of one Big number object.
Then, identical code except x
is stringified, rather than [x]
:
x = new Big('177.7e+457')
str = JSON.stringify( x )
JSON.parse( str, function ( k, v ) { return k === '' ? v : new Big(v) } )
// Returns the Big number's value as a string, rather than the Big number object.
I have to say I don't know anything about revivers, but this one doesn't look to me like it will only work with an array.
bignumber.js has the same behaviour.
Given this example x.div(y).plus(z).times(9).minus('1.234567801234567e+8').plus(976.54321).div('2598.11772') x.sqrt().div(y).pow(3).gt(y.mod(z))
And
A Big number is immutable in the sense that it is not changed by its methods.
It means that above example creates something like 11 unnecessary objects. Is there plans to support a lazy evaluation?
Instead of doing something like:
var number;
try {
number = Big(userInput);
} catch(error) {
// handle invalid number
}
It would be useful to have something like:
if (!Big.test(userInput)) {
// handle error
return;
}
var number = new Big(userInput);
Currently I'm using something like:
if (!/^\d+(\.\d*)?$/.test(userInput)) {
// handle error
return;
}
var number = new Big(userInput);
Which the regex doesn't necessarily cover all cases. I think I actually have a more complex one. Rather than digging up a good regex or relying on try/catch it would be nice if there was a way to validate the input using Big.
This could also be added to BigNumber or Decimal as well.
The RM and DP properties are global to all instances. If a user wishes to use a specific rounding mode or precision for a single operation (to which those properties apply) they would need to save any previous value, set the new value, and then reset the old value. If their operation has multiple async steps then they would need to be careful to do this every time.
It would make such use safer if it was possible to specify these settings on a per operation level. Originally I thought on a per instance could make sense too, but since it really is isolated to the operation that is where I would start. Possibly as an options argument to the related function calls.
Happy to do the PR but wanted to get some perspective on why these were global in the first place (possibly some benchmark or design reason).
Thoughts?
Related documentation:
http://mikemcl.github.io/big.js/#dp
The following warning is received, when installing on node.js:
npm WARN engine [email protected]:wanted: {"npm":"~1.2.10"} (current:
{"node":"v0.10.26","npm":"1.4.3"})
The warning is due to "npm":"~1.2.10"
in package.json, as the curent version of npm is 1.4.3. Perhaps line "npm":"~1.2.10"
can be changed to "npm":"*"
.
hi,
Now, new Big('+9')
throws a NaN exception.
It will be nice to treat it as valid input.
It would be nice to have an ability to format a number with decimal + thousands separators:
100000 -> 100,000
12345.345 -> 12,345.345
thank you
Suggestion: describe in the readme how these three libraries differ. AFAICT, big.js only supports base 10, whereas bignumber.js supports arbitrary bases. But what distinguishes decimal.js from big.js?
"big": "*"
is included in my package.josn file, however npm install
seams to fetch a completely different module, not this one.
Would it be possible to publish the module on npm?
This is mainly for the rounding option. Right not it's global, so unless I always want 0, 1 or 2 everywhere it's always possible to mess it up due to ajax potentially triggering a chain that executes one while another is running somewhere else.
eg.
Big.DP = 0;
Big.RM = 1;
var x = Big('7'); // RM is 1
var math = BigMath({'RM': 0}); // original defaults for others
var y = math.Big('7'); // RM is 0
console.log(x.div(2)); // "4"
console.log(y.div(2)); // "3"
var z = Big('2'); // RM is 1
console.log(y.div(x)); // "3" RM of a left part is always used
For reference, the following:
var math = {};
math['Big'] = $.extend({}, Big);
Will not work; because it's a function. But even if cloning the object worked, having the functionality built in may be more reliable/desirable.
What's the reasoning behind throwing exceptions like throw NaN
? I believe this should be at least wrapped in new Error()
(kind of similar to exceptions in bignumber.js).
For example, if new Big(NaN)
throws inside Express route handler, response is standard HTTP 404 (for some reason) instead of stack trace and such:
app.get('/', function () { throw NaN; })
// -> Returns `Cannot GET /` with status code 404.
Since the interpreter prefers the result of valueOf
when coercing an object to a number and toString
when coercing a number to a string, having valueOf
throw an exception instead of just returning a string value could help users track down accidental conversions to the native number type (this is especially true when integrating into an existing codebase).
For example:
var a = Big('1');
var b = Big('3');
var c = Big('20');
if(a < b) console.log('This works correctly in some cases...');
if(c > a) console.log('...and that\'s what makes bugs like this easy to overlook.');
if(c > b) console.log('The statement is not run because "20" is lexically less than "3".');
Consider a patch like this:
Big.prototype.valueOf = function valueOf() {
throw new TypeError('Conversion of Big.js object to native number is not supported.');
};
Now:
if(a < b) console.log('An exception is thrown before this is executed.');
+a; // => throws TypeError
Number(a); // => throws TypeError
String(a); // => "1"
If breaking backward compatibility is an issue, this could be placed behind a flag (Big.whinyValueOf
?).
I'd be happy to write a patch, add some tests, and submit a pull request if this is something others think may be helpful.
There is a npm package called big and it's this one https://www.npmjs.com/package/big
I found it because I tried npm install big and didn't get what I expected.
You could state in the README that there is no npm package for your library and the way to install it is by downloading the files. IMHO a better way would be to rename it a create a npm package (principle of least surprise), which would also give us an easy way to keep our files up to date.
Do i have to implement my own?
Big.DP allows you to specify the maximum decimal places when printing out instances. Is it possible to specify minimum number of DP?
This is an enhancement, and I can just do it myself, though I figured I'd contact you about it. What would be nice is to use 3 letter aliases for many of the functions
Example
.minus
-> .sub
.plus
-> .add
.times
-> .mul
Many people, myself included create vector2's in this manner. In addition, the three letters also for kinder code looks
a.minus(b)
.div(c)
.times(d)
.plus(e)
a.sub(b)
.div(c)
.mul(d)
.add(e)
The change is simple and I've already done it myself. Just thought I'd throw out the idea to you. https://github.com/formula1/big.js/blob/mutable/big.js#L712
I would be happy to add the package.json in a PR
Looks like the toString function doesn't accept any arguments. The native toString method accepts a radix parameter so you can conver to octal, hex, etc...
BigNum(13).toString(16) // => "13"
(13).toString(16) // => "d"
Please add a list of the supported browsers in the README. Does big.js work in old IEs, especially IE8?
I know you can round something to the right of the decimal.
For example,
Big b = new Big(555.5555);
b.round(2); // 555.56
But what if I want to do something like the following?
b.round(-1); // 560
This doesn't appear to be supported, although it is in native Javascript.
Hello,
I have something like this
var d1 = new Big(210965.92);
var d2 = new Big(214068.36);
var d3 = new Big(215619.58);
var d4 = new Big(217170.8);
var result = d1.plus(d2).plus(d3).plus(d4);
console.log(result);
result is showing an object. How would I go about converting this object to a number? Is it safe to do Number(result) or is there a better way to do this?
Is big.js hosted on any CDNs? I couldn't find it on http://cdnjs.com/ or http://jster.net/.
How about extending the library with a nthroot function... Currently I'm extending mine with:
P['nthrt'] = P['nthroot'] = function (n)
{
var x = this, negate, approx;
// Convert n to a Big
n = new Big(n);
// Checking to see if root is negative
negate = n.mod(2) == 1 && x['s'] == -1;
if (negate)
x = x.times(-1);
// Initial nth root result (nth root = x to the power of 1 / n)
approx = x.pow(Big(1).div(n));
// Validating result & return
n = approx.pow(n);
if (x.minus(n).abs(x - n) < 1 && (x > 0 == n > 0))
return negate ? approx.times(-1) : approx;
};
Calculation is based on the contents of an article at http://cwestblog.com/2011/05/06/cube-root-an-beyond/
I'm using the .pow() method, and it's throwing "uncaught exception: !pow!"...
But I'm only using it in two cases where the exponent is Big(2) in and and Big(8) in the other, yet it's throwing this error. Those are nowhere near the size of MAX_POW, and they are integers, so ~~e is should be the same number.
Can you see what's wrong with it?
This caught me a bit by surprise but the toString
methods will return results in scientific notation by default. Using an arbitrary precision library I expect output to be the full number in decimal notation. Thoughts on changing the default to not use scientific notation and/or adding a way to disable scientific notation?
Related to #51 but I also expected the default behavior to be no scientific notation.
Have you compared its performance with other popular libraries?
Such as -
https://nodejsmodules.org/tags/bigint
I had a case when a string taken from an excel sheet cell throws Big.js Error for a value like "121.151". Changed the library to decimal.js and everything worked fine! There should be a minor parsing bug in the big.js. I've been using big.js for few months now, never experienced any other issues. Fantastic library.
In the Why are trailing fractional zeros removed from Big numbers? section:
x = new BigDecimal("1.0")
y = new BigDecimal("1.1000")
z = x.add(y) // 2.1000
x = new BigDecimal("1.20")
y = new BigDecimal("3.45000")
z = x.multiply(y) // 4.1400000
should be
x = new Big("1.0")
y = new Big("1.1000")
z = x.plus(y) // 2.1000
x = new Big("1.20")
y = new Big("3.45000")
z = x.times(y) // 4.1400000
It seems the round up does not work properly. 18.444
rounded up to 2 decimals, is returned as 18.44
instead of 18.45
as expected.
I think it'd be useful if you added a toJSON method, and I'd be happy if it simply was the same method as toString.
I'm doing decimal math, and then sending the result off to a web service. As it is, calling JSON.stringify() with a Big object results in an object with the s, e, & c properties, which isn't particularly useful.
a = Big("35574645658566154123167421602612501599027292892376953789935727685995746319130625029060962133178619189566393606058310479941192649978692083501533752989519");
b = Big("35574645658566154123167421602612501599027292892376953789935727685995746319095719562810881098083356946450455837483270721374817065586523398559131897259139");
c = a.minus(b);
The last digit "0" is missing in 'c'
In earlier releases, the cmp
comparator method was public on Big
instances, but it's now been made private.
Beyond the hassle of porting code that uses cmp
over to the various new comparators, there are still valid use cases for using cmp
directly, such as abstracting it into a custom comparator for higher-level objects.
If you think this is a good idea, please let me know and I'll take a crack at it and submit a PR. I don't want to do the work on my fork if it's going to be rejected when I submit the PR.
decimal.js has a nice decimalPlaces
function that could be incorporated to big.js (and bignumber.js)
Could we add a bower.json so that it is also available on bower?
A simple straight equation problem:
var p1 = {x:1, y:1};
var p2 = {x:4, y:5};
var a = Big(p2.y - p1.y).div(p2.x - p1.x); // 4/3, fine
var b = Big(p2.y).minus(a.times(p2.x)); // -1/3, fine
Big(p2.y).minus(b).div(a).valueOf() // 4, fine
Big(p1.y).minus(b).div(a).valueOf() // 0.99999 : problem, it should be 1
It might come from division.
I encounter the same problem on BigNumber.js.
MikeMcl,
This library is simply amazing! I was able to implement it instantly, and it has all the functionality I could ever want! Thank you!!!
One quick question: does toExponential() always print . as the decimal separator? If not, how can I force it to?
Thank you so much in advance!
I've got a set of objects that have a v
property. I'm using Big.js to add them together via .plus
. It seems like .plus
isn't working the way the docs imply (x.minus(0.1) // "0.2"
).
sum = BigDecimal(0);
valsByKey.each(function(i) {
console.log("sum: " + sum);
console.log("i.v: " + i.v);
return sum.plus(BigDecimal(i.v));
});
console.log("sum after loop: " + sum);
sum: 0
i.v: 1.44
sum: 0
i.v: 1.08
sum after loop: 0
sum: 0
i.v: 0.99
sum: 0
i.v: 0.6
sum after loop: 0
sum: 0
i.v: 0.6
sum after loop: 0
sum: 0
i.v: 0.72
sum after loop: 0
I'm using a loop here because the array sometimes has a single value -- reduce doesn't seem to deal with this instance.
But changing
return sum.plus(BigDecimal(i.v));
to
return sum = sum.plus(BigDecimal(i.v));
results in correct values.
Currently new Big(null)
crashes, what do you think about returning null
instead in this case?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.