Giter VIP home page Giter VIP logo

fraction.js's People

Contributors

2sb18 avatar endbug avatar infusion avatar mojoaxel avatar munrocket avatar offirmo avatar redelmann avatar selimc avatar theraccoonbear avatar timgates42 avatar tonyrippy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fraction.js's Issues

v4.3.0 causes "main" entry error

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

Not precise enough

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.

Unexpected behavior for string input with high precision

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?

Error with fraction.js

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.

typescript error with mixed type

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...

mathjs dependency error

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)

simplify to arbitrary 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.

Why encapsulate the underlying class?

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?

Limit to certain precision(s)?

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?

Bundling with Vite/Usage in SvelteKit

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?

No TypeScript type definitions

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.

Rewrite the code to esm?

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.

new Fraction(value) fails when not using en-US decimal format

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.

Support for "d:n" besides "d/n"

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()?

bigfraction.js: rounding fractions with very large numbers

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 Numbers.
This seems to break if the fraction components are large BigInts.
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

How to handle invalid parameter error in fraction JS.

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?

Non-breaking-space characters in fraction.js

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:

2 nbsp characters 160

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.

Reduce size of npm module - use an .npmignore to remove unnecessary files

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.

  • I suggest adding an .npmignore file to remove all unnecessary files from the module.
  • Might also want to add a .gitignore, e.g. for node_modules?
  • In package.json, change the 'main' to the minified version
  • Add to the .npmignore every file which is not involved in production code.
  • In particular the examples and tests, those should not be in npm module.

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!

Throw Error instances so that stack trace is maintained

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");
}

Throwing errors

Current realization of throwing errors fully ignore call stack and can't be used for some debug

https://github.com/infusion/Fraction.js/blob/71e151fd5ccf542018307cee4a3639f42254d231/fraction.js#L380-L382

This errors created one time and keep in themselves call stack of this expression, not of throwing like this

https://github.com/infusion/Fraction.js/blob/71e151fd5ccf542018307cee4a3639f42254d231/fraction.js#L273

For fix it, can be used function calls like this

// assign
Fraction['DivisionByZero'] = () => new Error("Division by Zero");


// usage
throw Fraction['DivisionByZero']();

License

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?

TypeScript doesn't like the example in the README

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.

TypeError: Cannot read property '0' of null

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)

.toString() method sometimes increases the number by 0.9999...

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...":

  • the characteristic (whole part of the number) is calculated by the line str += N / D | 0; (which, because float division is involved, will round up for 90)
  • 2 lines later, the mantissa part (decimal points) is calculated further, starting with N %= D; line - which incorrectly starts to create a long tail of trailing 9's at the end

The combined result (90.9999...) is bad for two reasons:

  1. Those 2 lines in combination are not dependant on eachother. Proposed fix:
      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.

  1. The integers being used in the example turned out to be > 2^53 which is the limit of integer-arithmetic precision for 64-bit floats... (try 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.

a = b.mul(c) alters b

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?

Question about `log`s & `pow`s in base 10

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?

Publish code on npm as ES5

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.

Error importing fraction.js/bigint

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?

typo in fraction.d.ts

There's a typo in fraction.d.ts:

simmplify(eps?: number): Fraction;

should be: simplify(eps?: number): Fraction;

Implement a .valueOf() method returning the number

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.

Bad link in README

This link in the README.md is bad. When used, you're presented with a 500 server error as seen below.

Screen Shot 2022-12-08 at 11 08 04 AM

math.Fraction.REDUCE doesn't work from mathjs 10.0.1

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

No license file

Absence of an explicit license file causes webjar deployment script to fail. Please consider adding one.

RequireError: unable to load module

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.

0.333 is returned as 333/1000

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?

base

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)"

Trailing 0's when casting a fraction to string

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

Common denominator for list of fractions

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).

Muller's recurrence formula

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());

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.