rawify / fraction.js Goto Github PK
View Code? Open in Web Editor NEWFraction is a rational numbers library written in JavaScript
Home Page: https://raw.org/article/rational-numbers-in-javascript/
License: MIT License
Fraction is a rational numbers library written in JavaScript
Home Page: https://raw.org/article/rational-numbers-in-javascript/
License: MIT License
Fraction.js:9 Uncaught TypeError: Object.defineProperty called on non-object
at Function.defineProperty ()
at Fraction.js:9:10
at a (factory.js:35:12)
at Object. (pureFunctionsAny.generated.js:22:38)
at u ((index):1:2157)
at Object. (main.cd1dd74d.chunk.js:1:292368)
at u ((index):1:2157)
at Object. (main.cd1dd74d.chunk.js:1:115856)
at u ((index):1:2157)
at Object. (main.cd1dd74d.chunk.js:1:785656)
(anonymous) @ Fraction.js:9
a @ factory.js:35
(anonymous) @ pureFunctionsAny.generated.js:22
Looks like josdejong/mathjs#3022 is being reproduced again. I am using mathjs version 11.10.1.
It looks like there is a non-standard space character at line 760, between the }
and else
:
str+= ")";
} else {
for (var i = dec; N && i--; ) {
str+= N / D | 0;
https://github.com/infusion/Fraction.js/blob/master/fraction.js#L760
because of that I can't load the library in a browser
So I'm building an app that uses fraction.js to parse text user input and perform conversions from/to fraction as well as multiplications. The app accepts input in multiple languages and is running into trouble because of locale.
A simplified use case:
const quantity = "1,5"; // note that this is valid decimal in Brazil (pt-BR)
const fraction = new Fraction(quantity);
The above use case fails with Error: Invalid argument
. If the user enters 1.5 for quantity, it will work.
As a solution, the consumer of Fraction
could simply pass an optional locale argument. When not provided, the library can either assume a locale or do what it is doing today.
There might be other edge cases, but this is the one I'm running into right now. Is this something beneficial for this library? If it is, I am willing to try and implement this and submit a PR.
Hi i'm use fraction.js
with create-react-app
but when i run build script in CRA it throw fails to minify error
So CRA recommend that publish npm with es5.
Some third-party packages don't compile their code to ES5 before publishing to npm. This often causes problems in the ecosystem because neither browsers (except for most modern versions) nor some tools currently support all ES6 features. We recommend to publish code on npm as ES5 at least for a few more years.
You can see detail this issue
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-build-fails-to-minify
Thank you for making a good library.
Absence of an explicit license file causes webjar deployment script to fail. Please consider adding one.
Error received when running or building project:
Cannot find module '... /node_modules/fraction.js/fraction'. Please verify that the package.json has a valid "main" entry
Hi, I'm not sure whether this has already been reported, but I couldn't find it on the other issues.
Currently the round
method relies on Math.round
, and for this it casts the fraction components to Number
s.
This seems to break if the fraction components are large BigInt
s.
Example:
const f = Fraction(
'4096521364329291093171203267930457883773806471006747502090792325598781148452473209851945763411024272894391273488328322013368343609851019491145409276190539874605556064161234242385897557393344605006326305605571158871450061093373390954679799512035955892117049982513332807024354592989233228381581210555649737459420836464060796645449',
'63723676445298091081155215910708472223644182207704751442955434135446516060522326437723594988807307437639337877044454216957092285156250000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'
);
console.log(f.round());
// RangeError: The number NaN cannot be converted to a BigInt because it is not an integer
Several methods like .mul()
or .div()
can take as parameter a number or a fraction.
However with this code:
import Fraction from 'fraction.js';
function foo(a: Fraction, b: number | Fraction) {
return a.mul(b);
}
I get this typescript error:
No overload matches this call.
The last overload gave the following error.
Argument of type 'number | Fraction' is not assignable to parameter of type 'NumeratorDenominator'.
Type 'number' is not assignable to type 'NumeratorDenominator'.ts(2769)
As woraround I can do this:
import Fraction from 'fraction.js';
function foo(a: Fraction, b: number | Fraction) {
if(b instanceof Fraction)
return a.mul(b);
return a.mul(b);
}
But I think it's useless...
Hello,
I'm having the following error when compiling TS:
Module not found: Error: Package path ./bigfraction is not exported from package /home/runner/work/project/node_modules/fraction.js (see exports field in /home/runner/work/project/node_modules/fraction.js/package.json)
The import statement that's failing is this:
import Fraction from 'fraction.js/bigfraction';
Is this no longer supported? If not, how can I import the big fraction version?
Current realization of throwing errors fully ignore call stack and can't be used for some debug
This errors created one time and keep in themselves call stack of this expression, not of throwing like this
For fix it, can be used function calls like this
// assign
Fraction['DivisionByZero'] = () => new Error("Division by Zero");
// usage
throw Fraction['DivisionByZero']();
This Library is great but I'm not sure if this is a bug or something else.
I'm expecting to get 1/3 from 0.333 but instead get 333/1000.
Am I missing something?
I was trying to debug an issue in my code that caused throwInvalidParam
to be called. Unfortunately throwing a string doesn't maintain the callstack. Thankfully the fix is pretty easy:
function throwInvalidParam() {
throw new Error("Invalid Param");
}
GitHub repo should contain most things, including source code, tests, and examples. The npm module should contain only the minimal code required to make the module work, to reduce total size and increase load speed.
Please add me as a collaborator on GitHub and npm if you want me to implement this on a feature branch and do pull request, it will reduce the size of my own bundle?
Thanks!
Fraction.js/LICENSE -> MIT License
Fraction.js/fraction.min.js -> Dual licensed under the MIT or GPL Version 2 licenses.
Fraction.js/fraction.js -> Dual licensed under the MIT or GPL Version 2 licenses.
Which is Fraction.js license? MIT ? MIT & GPLv2?
A user of math.js noticed some unexpected behavior when creating a Fraction
:
// works as expected:
new Fraction(4.166666666666667) // {s: 1, n: 25, d: 6}
// doesn't work as expected (the second value was coming from a BigNumber)
new Fraction('4.166666666666667')
// {s: 1, n: 4166666666666667, d: 1000000000000000}
new Fraction('4.166666666666666666666666666666666666666666666666666666666666667')
// {s: 1, n: 7602530730928912, d: 1824607375422939}
I guess this has something to do with round-off errors and the stop condition of the loop that tries to split the value into a fraction, but I don't really understand it. Do you have any ideas why this happens?
When running a test script I got an error Uncaught SyntaxError: Unexpected identifier
when loading fraction.js v2.4.0. This seems to be because there are two nbsp characters (char code 160) in the code of fraction.js. When your HTML file doesn't define an encoding like UTF-8, you get this error.
The two orange blocks shows where they are in the code:
Should be an easy fix to replace these two non-breaking-spaces with regular spaces, so fraction.js just works fine without having to define an encoding.
How to handle invalid parameter error in fraction JS.
var x = Fraction("10 .25");
This code will produce error. Uncaught errorConstructor {name: "InvalidParameter", stack: "InvalidParameter↵....
But I need to show an alert popup when this error happens how to do that?
Thanks for this library, it looks solid. I'm experimenting with integrating fraction.js into math.js, see the v2
branch. It works nicely!
It would be useful to define the valueOf()
method of a Fraction to return it's decimal value (same output as toNumber()
. That would allow JS to implicitly convert a Fraction to a number in operations like new Fraction(1,4) + 2
.
Hi,
First of all, thanks for the fantastic work on fractions.
I think I've figured out a bug with the flag math.Fraction.REDUCE allowing to reduce or not fractions automaticly.
With mathjs 10.0.0 the code :
math.Fraction.REDUCE = false;
var f = math.Fraction(3, 6);
console.log(f); // gives {s: 1, n: 3, d: 6, …}
From mathjs 10.0.1 the code :
math.Fraction.REDUCE = false;
var f = math.Fraction(3, 6);
console.log(f); // gives {s: 1, n: 1, d: 2, …}
Thus, it seems that from mathjs 10.0.1 the REDUCE flag has no more effect.
Thanks for your help.
Chris
@infusion is there a changelog somewhere? What breaking changes are there in v3?
This is not a request, but a hopefully respectful invitation to a discussion.
I already did it in my fork, and it seems to work for my use case browser TypeScript development without bundling.
I prepend at line 39 export default
in front of the first line of the IIFE, and at line ca. 877... replaced the export machinery with a simple return Fraction
. That's all.
But I am afraid it breaks a lot... Right?
Perhaps a build step to make a cjs version out of the esm version is needed? And browser-legacy and AMD as well?
But I don't know about AMD.
Note: complex.js is also affected.
There appears to be a character instead of a regular space character in this line of fraction.js, which I believe is causing a script error when running in Chrome.
When I include the library, I can't use instanceof
to test if an object is an instance of BigRational
since that class is encapsulated.
Can't the library just export the class instead of just a constructor?
See title for issue
The constructor new Fraction(...);
can take a string as the parameter, but it seems that it does not handle an empty string. I expect calling new Fraction("");
to either throw an error such as InvalidParameter or return a default value. However, the following TypeError occurs.
/path/fraction.js:187
if (B[A] === '-') {// Check for minus sign at the beginning
^
TypeError: Cannot read property '0' of null
at parse (/path/fraction.js:187:16)
at Fraction (/path/fraction.js:331:5)
I tested the recurrence formula reported in https://medium.com/@bellmar/is-cobol-holding-you-hostage-with-math-5498c0eb428b and it appears to me that iteration 11 Fraction.js suddenly goes wrong.
It should pass from "24502636/4912337" to "122336033/24502636" and instead it returns "150238955334780/30091301355083".
Could you please also make this check?
For reference my code is below (Chrome 68):
repeat = (n,f) => {[...Array(n)].forEach(f)};
muller = (y, z) => Fraction(108)
.sub(
Fraction(815).sub(
Fraction(1500)
.mul(z.inverse())
)
.mul(y.inverse())
);
x = [Fraction(4.25), Fraction(4)];
repeat(30, _ => x.unshift(muller(x[0], x[1])));
xf = x.map(_ => [_.toFraction(), _.toString()] );
console.table(xf.reverse());
Why when a Number
is converted to a Fraction
the library internally uses powers and logarithms in base 10? Shouldn't that potentially reduce floating-point precision? Why not base 2?
It's not precise enough:
var a = fraction('1.00001');
var b = fraction('3.2000000000001');
var actual = a.add(b); // get 4.200010000000099 but expect 4.2000100000001
I use it for money calculation, so this behaviour is not acceptable.
A nitpick: the git
tags for v4.2.1 - v4.3.1 seem to be missing, and could be useful to push to make it easier to compare released versions.
Sorry if this is obvious, but I can't seem to figure out how can I limit the precision of the output result in fraction to closest of 1/2, 1/4, 1/8 or 1/16, without these weird fractions such as 1/3?
Using fraction with the Vite bundler and TypeScript gives the following warning:
fraction.js doesn't appear to be written in CJS, but also doesn't appear to be a valid ES module (i.e. it doesn't have "type": "module" or an .mjs extension for the entry point). Please contact the package author to fix.
When attempting import Fraction from "fraction.js
the bundler throws the following error:
TypeError: __vite_ssr_import_2__.default is not a constructor
I've tried adding "fraction.js" to the vite config ssr.noExternal
and optimizeDeps.include
but that doesn't resolve the issue.
Note this error only occurs seemingly when server side rendering the page (using SvelteKit). If the lib is loaded client side, the library works as expected.
tsconfig.js has both "allowSyntheticDefaultImports": true
and "esModuleInterop": true
Any thoughts as to why the bundler is not liking importing Fraction on the server?
on deploy today give that error in mathjs:
Uncaught TypeError: Object.defineProperty called on non-object
at Function.defineProperty ()
at push../node_modules/mathjs/lib/esm/type/fraction/Fraction.js.Object.isClass (Fraction.js:9:1)
at assertAndCreate (factory.js:35:1)
at ./node_modules/mathjs/lib/esm/entry/pureFunctionsAny.generated.js (pureFunctionsAny.generated.js:22:1)
When I do an operation on a Fraction, the original Fraction is altered, for example:
var a = Fraction(0.5);
var b = Fraction(0.4);
var c = a.mul(b);
// a = 0.2 (!), b = 0.4, c = 0.2
// ...same with other operations
Is this intentional behavior?
There's a typo in fraction.d.ts:
simmplify(eps?: number): Fraction;
should be: simplify(eps?: number): Fraction;
Is there a way with the library to floor a given decimal input to a multiple of a fraction? I.e. new Fraction("0.9").simplify(Fraction("1/8")) => Fraction("7/8")
. Would there be any interest in adding this?
I'm sort of confused what the use case for the existing simplify
method is.
TypeScript doesn't like importing this module like
const Fraction = require('fraction.js'); // This expression is not constructable.
or
const { Fraction } = require('fraction.js'); // Module '"fraction.js"' has no exported member 'Fraction'.
You have to do
const Fraction = require('fraction.js').default;
However, all three work in vanilla JavaScript.
Bug when number of places is bigger than 21:
https://runkit.com/munrocket/fraction-js-test
Also not clear in documentation how you perform rounding, to result or to fractions?
"Fraction.js - ℚ in JavaSript"
JavaScript?
In Observable notebooks, I use F = require("fraction.js")
. However, this now results in RequireError: unable to load module
. I can fix it by changing it to F = require('[email protected]/fraction.js')
.
Is adding the version number mandatory? I’d like to always get the latest version, so not specifying the version number (assuming newer versions are always upwards compatible). Or is that considered unwise and bad practice?
I assume it is related to Native ES module support.
Please advise.
Sometimes using toString()
method returns a stringified number with trailing zeroes.
Example - enter that in your browser console:
var a = new Fraction(1); var b = new Fraction(0.99); var c = new Fraction(0.98); for (var i = 0; i < 100; i++) { a = a.mul(b).div(c); console.log(a.toString()); }
and you will see that numbers like: 1.455919622856570
, 1.470775945538780
, 1.485783863350400
Would be great to have type definitions for use with TypeScript. If I end up writing my own I'll send a PR, but regardless, it'd be handy.
Feature request: .toFraction()
returns "n/d"
. Sometimes, you need/prefer "n:d"
, e.g. when working in music theory or with aspect ratios.
My work around now is to add a separate function to the object returned by Fraction using Object.assign()
in a wrapper.
Also, would the separator be an extra argument to .toFraction()
or would it rather be a new function, e.g. .toRatio()
?
It would be helpful to be able to sort the numbers.
This link in the README.md is bad. When used, you're presented with a 500 server error as seen below.
Feature request: support for creating common denominator for list of fractions.
I need Fraction(4, 4)
to return {s: 1, n: 4, d: 4}
instead of simplifying it to {s: 1, n: 1, d: 1}
.
Also, I need a function that takes a list like:
[
Fraction(2, 1),
Fraction(3, 2),
Fraction(4, 3),
Fraction(5, 4),
Fraction(6, 5),
]
and returns:
[
{s: 1, n: 120, d: 60},
{s: 1, n: 90, d: 60},
{s: 1, n: 80, d: 60},
{s: 1, n: 75, d: 60},
{s: 1, n: 72, d: 60},
]
That is, the fractions have a common denominator equal to lcm(1,2,3,4,5,6) → 60
. The converted list of fractions is easier to compare (just sort on the nominator).
When flotting numbers are used fractions are round.
Fraction('999999.99') ===Fraction(999999.99) // returns false
999999.99 == 999999.99 // returns true
Fraction('999999.99').valueOf() // 999999.99
Fraction(999999.99).valueOf() // 1000000
Source code suggest http://www.johndcook.com/blog/2010/10/20/best-rational-approximation/
Is there any workaround to this or do we know when this approximation is fired in?
if you take a number like (new Fraction({ s: 1, n: 211161308301803970, d: 2346236758908933 })).toString()
which is essentially exactly 90 (did my calculations on paper) - then while casting it to string using the .toString()
function, it will return "90.9999...":
str += N / D | 0;
(which, because float division is involved, will round up for 90)N %= D;
line - which incorrectly starts to create a long tail of trailing 9's at the endThe combined result (90.9999...) is bad for two reasons:
var characteristic = N / D | 0;
str += characteristic;
N -= characteristic * D;
N %= D;
vs.
str += N / D | 0;
N %= D;
It doesn't remove the floating arithmetic errors from the equation but at least does not introduce an additional gap of potentially huge errors.
Math.pow(2, 53) === Math.pow(2, 53) + 1
) So yeah, the solution for that will probably be to introduce bignumber as the fundamental value. I'd really like to say it only happens in rare cases but I can't - doing a couple of simple .mult / .div operations on quite simple fractions may quickly lead you into huge nominator/denominator integers.Suggestion:
add support for base other than 10
example:
new Fraction(1,18).toString(10); // "0.0(5)"
new Fraction(1,18).toString(11); // "0.(067A43)"
new Fraction(1,18).toString(12); // "0.08"
new Fraction(1,18).toString(15); // "0.0C(7)
new Fraction(1,18).toString(18); // "0.1"
new Fraction(1,18).toString(20); // "0.1(248HFB)"
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.