Skip to content
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

Add support for fractionalizing common decimals #401

Open
qJake opened this issue Apr 3, 2015 · 6 comments
Open

Add support for fractionalizing common decimals #401

qJake opened this issue Apr 3, 2015 · 6 comments

Comments

@qJake
Copy link

qJake commented Apr 3, 2015

It would be awesome if there were support for fractionalizing certain numbers. I know it's a pretty short extension method, but I already use Humanizer elsewhere so this would be a great addition for me.

Examples:

1 -> 1
1.25 -> 1 1/4
2.5 -> 2 1/2
4.33 -> 4 1/3
1.8 -> 1 4/5
0.75 -> 3/4

Optionally, you could use the ASCII fraction characters when possible:

1 -> 1
1.25 -> 1¼
2.5 -> 2½
4.33 -> 4 1/3
1.8 -> 1 4/5
0.75 -> ¾

What I'm not sure of is how far you'd want to go ... personally, I don't see a benefit to fractionalizing anything beyond fifths (0.2).

@qJake
Copy link
Author

qJake commented Apr 3, 2015

Here's the method I ended up writing, I'm sure it has some edge cases and bugs but it's probably a good start:

        public static string Fractionalize(this decimal dec)
        {
            string fractionalPart = (dec - Math.Truncate(dec)).ToString("0.00");
            string wholePart = ((int)Math.Floor(dec)).ToString();

            if (fractionalPart == "0.00")
            {
                return wholePart;
            }

            string result = dec > 1 || dec < 0 ? wholePart : "";

            switch (fractionalPart)
            {
                case "0.20":
                    result += " 1/5";
                    break;
                case "0.25":
                    result += " ¼";
                    break;
                case "0.30":
                case "0.33":
                case "0.34":
                    result += " 1/3";
                    break;
                case "0.40":
                    result += "2/5";
                    break;
                case "0.50":
                    result += " ½";
                    break;
                case "0.60":
                    result += "3/5";
                    break;
                case "0.66":
                case "0.67":
                    result += "2/3";
                    break;
                case "0.75":
                    result += " ¾";
                    break;
                case "0.80":
                    result += " 4/5";
                    break;
            }

            return result.Trim();
        }

@MehdiK
Copy link
Member

MehdiK commented Apr 5, 2015

Thanks for the suggestion @qJake.

This could be useful; although as you said I'm not sure how far one might want to push it and the desired behavior could get really subjective.

I'll keep this here asking users to vote on it. If enough people want it, we'll think about an implementation.

A couple of considerations:

  • This should be localisable.
  • It should deal with every fractional part and not just those listed in your switch case; i.e. what happens for 0.31 and 0.55?
  • How do we allow configurability around rounding and precision?

@hazzik
Copy link
Member

hazzik commented Apr 13, 2015

what happens for 0.31

31/100; 0.31; or 14/45

what happens for ... 0.55

11/20; 0.55; or 5/9

See this gist: https://gist.github.com/hazzik/4e292aba1b748e2271e7

@qJake
Copy link
Author

qJake commented Apr 13, 2015

You would probably have to specify some sort of tolerance, as well as a maximum fractional part. For example, 0.31, with a maximum fractional part of 5 and a tolerance of ±0.03 would yield "1/3", but the same number with a maximum fractional part of 50 would yield 14/45.

So the fractional part is the highest possible denominator, and the tolerance is the maximum amount, either way, that the number can be shifted to fit into a "nice" fraction (e.g. 0.33 / 0.34 for 1/3).

Number Tolerance Maximum Denominator Output Status
0.34 ± 0.1 5 1/3
0.34 ± 0.0 5 0.34
0.34 ± 0.0 55 17/50
0.3 ± 0.4 3 1/3
0.199 ± 0.1 5 2/5
0.199 ± 0.1 3 0.199
0.1 ± 0.0 10 1/10
0.11 ± 0.0 10 0.11

I realize this complicates the feature quite a bit, but if done right, this could be very useful! 😃

@MehdiK
Copy link
Member

MehdiK commented Apr 17, 2015

Sounds great to me. Show me the PR :p

@eytan600
Copy link

eytan600 commented Aug 6, 2023

Hi, @MehdiK!
As of today, there is still no support for the conversion of fractions?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants