-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
feat: add decimal to fraction algorithm #1439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make clear what the spec of this is. What is the accuracy? If it's in decimal places, why do you need any complicated logic beyond rounding, and choosing the appropriate power of ten for the denominator?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I have answered all your questions, and resolved those, what I think I should.
I'd like to reiterate this:
Please make clear what the spec of this is. What is the accuracy? If it's in decimal places, why do you need any complicated logic beyond rounding, and choosing the appropriate power of ten for the denominator?
Code-wise, it seems you misunderstood my point. I'm asking for a "flattening" of the code using early returns / throws. The logic should be something like "if input is invalid, throw. if input is trivial (integer), return early. now do the actual meaty logic (if we got here, we didn't return or throw already)".
I'd like to reiterate this:
Please make clear what the spec of this is. What is the accuracy? If it's in decimal places, why do you need any complicated logic beyond rounding, and choosing the appropriate power of ten for the denominator?
Code-wise, it seems you misunderstood my point. I'm asking for a "flattening" of the code using early returns / throws. The logic should be something like "if input is invalid, throw. if input is trivial (integer), return early. now do the actual meaty logic (if we got here, we didn't return or throw already)".
If we got the number which is not an integer, then what!? Or if the is input is not a number even, then I will wait for what? Please clear me.😟
If we got the number which is not an integer, then what!? Or if the is input is not a number even, then I will wait for what? Please clear me.😟
The logic should stay the same, it's just about how you write it. Currently the code is a mess of if
-else
s - e.g., else
s to throw in error cases. What I'm proposing is to use early return
s and throw
s to clean it up structure-wise. Suppose you have
function decimalToFraction(decimal) { if (typeof decimal === "number") { if (Number.isInteger(decimal)) { return [decimal, 1] } else { // this is where the logic for converting a valid decimal that isn't an integer to a fraction goes... } } else { throw "invalid type" } }
then this would be better written as
function decimalToFraction(decimal) { if (typeof decimal !== "number") throw "invalid type" if (Number.isInteger(decimal)) return [decimal, 1] // this is where the logic for converting a valid decimal that isn't an integer to a fraction goes... }
@appgurueu fixed all issues you have mentioned.
@appgurueu any progress?!
@appgurueu waiting for your updated review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see this robustly implementing (or even precisely defining) the problem yet; the code is also currently still quite dirty.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please formulate this mathematically - something like "fraction - num <= 10^-accuracy".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are all these examples really useful? 0.5
and 0.25
for example seem redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're still not using guards here; these checks are all redundant with the if-throws in the else
. You just need to move the if-throws to the top of the function, making them guards.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These "guards" should all be moved to the top of the function. They could also be simplified a bit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The NaN check is redundant with the negated isFinite
check.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is called "shortening" the fraction. number
and len
are odd names for "numerator" and "denominator".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again a redundant comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not apparent to me why this is correct: Isn't number.length
the length of the whole number (without the period, in digits), not just the "fractional" part after the period here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
String manipulation for manipulating numbers is dirty here. Just multiply your numerator by the denominator, then round. Shouldn't the denominator be determined by the accuracy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a hacky way to deal with "repeating" fractional parts, and I'd argue that it solves the wrong problem. Since we're dealing with finite-size numbers (floats) here, there are no "repeating" decimals; we can't distinguish a "repeating" decimal from a "deliberately ending decimal". We need to treat both the same (it seems "accuracy" is more of a "threshold" of when you consider a decimal repeating?).
In fact, all floats can even be represented exactly as fractions (though perhaps maybe not as fractions of floats, that might get hairy towards some edge cases) where the denominator is a power of two and the numerator is an integer.
I wouldn't exclude the possibility that some special provisions for repeating decimals may be useful, but then what problem this exactly solves (and how) and what guarantees it makes should be explicitly stated.
Uh oh!
There was an error while loading. Please reload this page.
Open in Gitpod know more
Describe your change:
Checklist:
Example:
UserProfile.js
is allowed butuserprofile.js
,Userprofile.js
,user-Profile.js
,userProfile.js
are notFixes: #{$ISSUE_NO}
.