Comments (4)
I'm not sure that accidental conversion to numbers is enough of a problem to introduce a breaking change, and there is no such conversion in your example, just string comparisons. The if
statements would actually work okay if one or both of the operands were converted to a number, e.g. +c > b
.
Have you a stronger example of where valueOf
returning a string can be a problem?
If it was to be changed, I think I'd prefer it to return a number rather than throw. Or perhaps return a number if a conversion was possible, and throw on underflow to zero and overflow to Infinity
.
from big.js.
Okay, I suppose there are two observations here:
- Lexical comparison of the string representations of Big.js objects is almost certainly not what a user would want if he writes
a < b
. - In general, the conversion of a Big.js object into a native (less precise, floating point) number is probably undesirable. After all, if a user has taken the time to use this library, he presumably has deemed the native arithmetic insufficient for his needs.
I don't have another example of anything like (1) where valueOf
returning a string particularly matters; however, the issue of (2) is present if any of the native number operators or Math
methods are used on a Big.js object. Again, I imagine this mainly happening by mistake in process of adopting Big into an existing code-base.
As you suggested, valueOf
could be defined so that it returns a number and only throws when the value cannot be precisely expressed as a native number:
Big.prototype.valueOf = function valueOf() {
var nativeNumber = Number(this.toString());
try {
if(this.eq(nativeNumber.toString(10))) {
return nativeNumber;
}
}catch(e){}
throw new TypeError(this.toString() + ' cannot be represented as a native number');
};
var a = Big('1');
var b = Big('3');
var c = Big('20');
if(a < b && c > a && c > b) console.log('Comparison now works like I would intuitively expect if I mistakenly use the native comparison operators.');
+Big('34342413412348923147981237593428759345322'); // => TypeError
This would solve (1); however, it still leaves the user open to the same kind of precision loss issues that probably inspired him to start use an arbitrary precision decimal library in the first place. An overused example being:
Big('0.1') + Big('0.2'); // => 0.30000000000000004
Personally, I would rather have an exception be thrown if the interpreter tries to convert a Big.js object directly to a native number as it is almost certainly a mistake.
That being said, as you pointed out, if someone is depending on the current behavior of valueOf, this would be a breaking change. Warning users about a potential misuse of the library may not justify breaking backward compatibility.
from big.js.
I think it's more in keeping with JavaScript's flexible type system and the no-fuss, easy-to-use ethos of big.js that a Big number allow itself to be coerced to a primitive number when used in an arithmetic or Math operation.
You "imagine this mainly happening by mistake", but I think the contrary is more likely.
I appreciate your analysis, and agree that it would be safer and perhaps more proper to throw, but I would prefer to err on the side of being too permissive than too strict.
The original reason for valueOf
returning a string rather than a number, was that only the former represents the full 'value of' a Big number.
There is also the option of adding a toNumber
method, but when I considered that before, #21, I didn't think it necessary.
I'm not yet rejecting your suggestion, and I'll think about it further.
from big.js.
It took a while, but I've just added a strict mode in v6.0.0 which causes an error to be thrown if a primitive number is passed to the Big constructor, or if valueOf
is called, or if toNumber
is called on a Big which cannot be converted to a primitive number without a loss of precision.
Big.strict = false; // default
x = new Big(0.1);
y = new Big('1.000000000000000000001');
y + 2; // '1.0000000000000000000012'
y.toNumber(); // 1
Big.strict = true;
x = new Big(1); // 'TypeError: [big.js] String expected'
y = new Big('1.000000000000000000001');
y + 2; // 'Error: [big.js] valueOf disallowed'
y.toNumber(); // 'Error: [big.js] Imprecise conversion'
Thanks for your input.
from big.js.
Related Issues (20)
- Uncaught ReferenceError: Big is not defined HOT 2
- Circular dependency leads to error when recursively accessing enumerable properties HOT 1
- [Feature Request] Static properties for Comparisons HOT 1
- [Feature Request] Conversion between Big and BigInt HOT 2
- Performance of pow function HOT 2
- TS7016: Could not find a declaration file for module 'big.js' HOT 2
- rounding 9.9 gives improper coefficient HOT 1
- How to get rid of decimal places of a number? HOT 1
- Rounding issue HOT 1
- Precision issue with big.js HOT 3
- Support for Comparision operators HOT 2
- Queries for big.js and bignumber.js HOT 2
- typo in license filename HOT 1
- Nullish input of Big constructor results in Error HOT 1
- Can Big.js return Infinity when divide 0? HOT 1
- Add the toSignificantDigits method HOT 1
- Webpack type error angular HOT 1
- Ecma TC39 decimal proposal feedback?
- Cannot divide two Big Numbers
- comperation between two numbers, getting wrong HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from big.js.