কীভাবে ভাসমানগুলি মানব-পঠনযোগ্য ভগ্নাংশে রূপান্তর করবেন?


103

ধরা যাক আমাদের আছে 0.33, আমাদের আউটপুট দরকার 1/3
আমাদের যদি থাকে তবে আমাদের 0.4আউটপুট করতে হবে 2/5

এই ধারণাটি হ'ল এটিকে মানব-পঠনযোগ্য করে তুলুন যাতে ব্যবহারকারী " x এর অংশগুলি y এর বাইরে " আরও ভাল করে ডেটা বোঝার উপায় হিসাবে বুঝতে পারে।

আমি জানি যে শতাংশগুলি একটি ভাল বিকল্প তবে আমি ভাবছিলাম যে এটি করার কোনও সহজ উপায় আছে কিনা?


.33=> "1/3"উদাহরণস্বরূপ উদ্বেগ আমাকে; আমি আশা .33=> "33/100"। আমি .33...অবশ্যই আপনাকে অবশ্যই বোঝাতে চাইছি , তবে এটি একটি সমস্যাটি উদ্ঘাটিত করে - আমরা একটি অ্যালগরিদমে স্থির হওয়ার আগে আমাদের প্রত্যাশিত আচরণের বিষয়ে সিদ্ধান্ত নেওয়া উচিত। @ দেবিলস্কির পাইথন উত্তরটি ব্যবহার করে .limit_denominator()যা 10 ^ 7 এর সর্বাধিক ডোনোমিনেটরের ডিফল্ট হয়; সম্ভবত অনুশীলন একটি ভাল ডিফল্ট, কিন্তু এই এখনও বাগ পরিচয় করিয়ে দিতে পারেন যদি আপনি সতর্ক থাকুন না হন, এবং না প্রত্যাবর্তন "33/100"মধ্যে .33কেস।
dimo414

যাই হোক না কেন language- specifc বৈশিষ্ট্য পাওয়া যায়। আপনি যা জিজ্ঞাসা করছেন তা অস্পষ্ট, যদি প্রকৃতপক্ষে এটি শর্তগুলির মধ্যে কেবল দ্বন্দ্ব না হয়।
মারকুইস

উত্তর:


70

আপনি যা চেয়েছিলেন ঠিক সেভাবেই পেতে ডেভিড এপস্টিনের রিয়েল নম্বর সি কোডের যুক্তিযুক্ত সান্নিধ্য খুঁজে পেয়েছি । এটি অবিরত ভগ্নাংশ এবং খুব দ্রুত এবং মোটামুটি কমপ্যাক্টের তত্ত্বের ভিত্তিতে।

আমি নির্দিষ্ট সংখ্যার এবং ডিনোমিনিটর সীমাতে এর জন্য কাস্টমাইজ করা সংস্করণগুলি ব্যবহার করেছি।

/*
** find rational approximation to given real number
** David Eppstein / UC Irvine / 8 Aug 1993
**
** With corrections from Arno Formella, May 2008
**
** usage: a.out r d
**   r is real number to approx
**   d is the maximum denominator allowed
**
** based on the theory of continued fractions
** if x = a1 + 1/(a2 + 1/(a3 + 1/(a4 + ...)))
** then best approximation is found by truncating this series
** (with some adjustments in the last term).
**
** Note the fraction can be recovered as the first column of the matrix
**  ( a1 1 ) ( a2 1 ) ( a3 1 ) ...
**  ( 1  0 ) ( 1  0 ) ( 1  0 )
** Instead of keeping the sequence of continued fraction terms,
** we just keep the last partial product of these matrices.
*/

#include <stdio.h>

main(ac, av)
int ac;
char ** av;
{
    double atof();
    int atoi();
    void exit();

    long m[2][2];
    double x, startx;
    long maxden;
    long ai;

    /* read command line arguments */
    if (ac != 3) {
        fprintf(stderr, "usage: %s r d\n",av[0]);  // AF: argument missing
        exit(1);
    }
    startx = x = atof(av[1]);
    maxden = atoi(av[2]);

    /* initialize matrix */
    m[0][0] = m[1][1] = 1;
    m[0][1] = m[1][0] = 0;

    /* loop finding terms until denom gets too big */
    while (m[1][0] *  ( ai = (long)x ) + m[1][1] <= maxden) {
        long t;
        t = m[0][0] * ai + m[0][1];
        m[0][1] = m[0][0];
        m[0][0] = t;
        t = m[1][0] * ai + m[1][1];
        m[1][1] = m[1][0];
        m[1][0] = t;
        if(x==(double)ai) break;     // AF: division by zero
        x = 1/(x - (double) ai);
        if(x>(double)0x7FFFFFFF) break;  // AF: representation failure
    } 

    /* now remaining x is between 0 and 1/ai */
    /* approx as either 0 or 1/m where m is max that will fit in maxden */
    /* first try zero */
    printf("%ld/%ld, error = %e\n", m[0][0], m[1][0],
           startx - ((double) m[0][0] / (double) m[1][0]));

    /* now try other possibility */
    ai = (maxden - m[1][1]) / m[1][0];
    m[0][0] = m[0][0] * ai + m[0][1];
    m[1][0] = m[1][0] * ai + m[1][1];
    printf("%ld/%ld, error = %e\n", m[0][0], m[1][0],
           startx - ((double) m[0][0] / (double) m[1][0]));
}

6
আপনারা যারা রুবিতে সমাধান খুঁজছেন তাদের জন্য আমরা ভাগ্যবান! ক্রিস্টোফার লর্ড একটি রুবি রত্নে উপরের অ্যালগরিদমটি প্রয়োগ করেছেন। দেখুন christopher.lord.ac/fractions-in-ruby এবং rubygems.org/gems/fraction
Shedd

6
সচেতন থাকুন যে কয়েকটি প্রান্তের কেস রয়েছে যা এই কোডটি খুব ভালভাবে পরিচালনা করে না: যখন -1.3333333 দেওয়া হয় 4 এর সর্বাধিক ডিনোমিনেটরের সাথে এটি 3 / 33333e-08 এর ত্রুটির সাথে 4 / -3 প্রদান করে এবং একটি ত্রুটির সাথে = -5/4 দেয় -8.333330e-02, যা সঠিক। কিন্তু যখন একই সর্বোচ্চ ডিনোমিনিটারের সাথে -1.33333337 দেওয়া হয়, তখন এটি 12121211 / -9090908 ত্রুটির ত্রুটির সাথে = 4.218847e-15 এবং -4.63 -3.666667e-08 এর ত্রুটিযুক্ত -4 / 3 এ পরিণত হয়, যা সঠিক নয়। এটি বিশেষত মুখ্য ভাসমান বিন্দু যেমন -4/3 হিসাবে অ্যালগরিদম উপস্থাপন করার সময় একটি সমস্যা, যা এর মতো ভুল ফলাফল দেয়।
edsko

26

পাইথন থেকে ২.6 রয়েছে fractions মডিউলটি রয়েছে।

(ডক্স থেকে উদ্ধৃতি।)

>>> from fractions import Fraction
>>> Fraction('3.1415926535897932').limit_denominator(1000)
Fraction(355, 113)

>>> from math import pi, cos
>>> Fraction.from_float(cos(pi/3))
Fraction(4503599627370497, 9007199254740992)
>>> Fraction.from_float(cos(pi/3)).limit_denominator()
Fraction(1, 2)


2
@Debilski ওপি এর মধ্যে কোনটি language agnosticএবং algorithmট্যাগ আপনার উত্তর সন্তুষ্ট করে?
ভ্লাদর

2
@ ভ্ল্যাডার ওয়েল, আমি এই উত্তরটি প্রায় years বছর আগে লিখেছিলাম (এবং প্রশ্নটি জিজ্ঞাসা করার এক বছরেরও বেশি সময় পরে), আমার ধারণা আমার তখনকার যুক্তিটি কী ছিল তা আমি আর জানি না। সম্ভবত আমি এই মন্তব্যটির উল্লেখ করছি: স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 95727/… ওটোও এটিও হতে পারে যে এই উত্তরটি অন্য একটি প্রশ্ন থেকে একত্রিত করা হয়েছে been এই সমস্ত বছর পরে কে বলতে পারে…
দেবিলস্কি

ভগ্নাংশ মডিউল দ্বারা ব্যবহৃত অ্যালগরিদম সম্পর্কে আপনি কয়েকটি বাক্য যুক্ত করতে পারেন (এবং পাইথন 3 এর জন্য সম্ভবত আপনার উত্তর আপডেট করুন)।
einpoklum

21

যদি আউটপুটটি কোনও মানব পাঠককে ফলাফলের ক্রমটির দ্রুত ছাপ দেয়, তবে এটি "113/211" এর মতো কোনও কিছু ফেরত দেওয়ার কোনও বুদ্ধি করে না, সুতরাং আউটপুটটি নিজেকে এক-অঙ্কের সংখ্যা (এবং সম্ভবত 1 / 10 এবং 9/10)। যদি তা হয় তবে আপনি পর্যবেক্ষণ করতে পারেন যে কেবলমাত্র 27 টি আলাদা ভগ্নাংশ রয়েছে।

যেহেতু আউটপুট তৈরির জন্য অন্তর্নিহিত গণিতটি কখনই পরিবর্তিত হবে না, এর সমাধান হ'ল একটি বাইনারি অনুসন্ধান ট্রিটিকে কেবল হার্ড-কোড করা উচিত, যাতে ফাংশনটি সর্বাধিক লগ (27) 4 = 4 3/4 তুলনা করে। এখানে কোডের একটি পরীক্ষিত সি সংস্করণ দেওয়া আছে

char *userTextForDouble(double d, char *rval)
{
    if (d == 0.0)
        return "0";

    // TODO: negative numbers:if (d < 0.0)...
    if (d >= 1.0)
        sprintf(rval, "%.0f ", floor(d));
    d = d-floor(d); // now only the fractional part is left

    if (d == 0.0)
        return rval;

    if( d < 0.47 )
    {
        if( d < 0.25 )
        {
            if( d < 0.16 )
            {
                if( d < 0.12 ) // Note: fixed from .13
                {
                    if( d < 0.11 )
                        strcat(rval, "1/10"); // .1
                    else
                        strcat(rval, "1/9"); // .1111....
                }
                else // d >= .12
                {
                    if( d < 0.14 )
                        strcat(rval, "1/8"); // .125
                    else
                        strcat(rval, "1/7"); // .1428...
                }
            }
            else // d >= .16
            {
                if( d < 0.19 )
                {
                    strcat(rval, "1/6"); // .1666...
                }
                else // d > .19
                {
                    if( d < 0.22 )
                        strcat(rval, "1/5"); // .2
                    else
                        strcat(rval, "2/9"); // .2222...
                }
            }
        }
        else // d >= .25
        {
            if( d < 0.37 ) // Note: fixed from .38
            {
                if( d < 0.28 ) // Note: fixed from .29
                {
                    strcat(rval, "1/4"); // .25
                }
                else // d >=.28
                {
                    if( d < 0.31 )
                        strcat(rval, "2/7"); // .2857...
                    else
                        strcat(rval, "1/3"); // .3333...
                }
            }
            else // d >= .37
            {
                if( d < 0.42 ) // Note: fixed from .43
                {
                    if( d < 0.40 )
                        strcat(rval, "3/8"); // .375
                    else
                        strcat(rval, "2/5"); // .4
                }
                else // d >= .42
                {
                    if( d < 0.44 )
                        strcat(rval, "3/7"); // .4285...
                    else
                        strcat(rval, "4/9"); // .4444...
                }
            }
        }
    }
    else
    {
        if( d < 0.71 )
        {
            if( d < 0.60 )
            {
                if( d < 0.55 ) // Note: fixed from .56
                {
                    strcat(rval, "1/2"); // .5
                }
                else // d >= .55
                {
                    if( d < 0.57 )
                        strcat(rval, "5/9"); // .5555...
                    else
                        strcat(rval, "4/7"); // .5714
                }
            }
            else // d >= .6
            {
                if( d < 0.62 ) // Note: Fixed from .63
                {
                    strcat(rval, "3/5"); // .6
                }
                else // d >= .62
                {
                    if( d < 0.66 )
                        strcat(rval, "5/8"); // .625
                    else
                        strcat(rval, "2/3"); // .6666...
                }
            }
        }
        else
        {
            if( d < 0.80 )
            {
                if( d < 0.74 )
                {
                    strcat(rval, "5/7"); // .7142...
                }
                else // d >= .74
                {
                    if(d < 0.77 ) // Note: fixed from .78
                        strcat(rval, "3/4"); // .75
                    else
                        strcat(rval, "7/9"); // .7777...
                }
            }
            else // d >= .8
            {
                if( d < 0.85 ) // Note: fixed from .86
                {
                    if( d < 0.83 )
                        strcat(rval, "4/5"); // .8
                    else
                        strcat(rval, "5/6"); // .8333...
                }
                else // d >= .85
                {
                    if( d < 0.87 ) // Note: fixed from .88
                    {
                        strcat(rval, "6/7"); // .8571
                    }
                    else // d >= .87
                    {
                        if( d < 0.88 ) // Note: fixed from .89
                        {
                            strcat(rval, "7/8"); // .875
                        }
                        else // d >= .88
                        {
                            if( d < 0.90 )
                                strcat(rval, "8/9"); // .8888...
                            else
                                strcat(rval, "9/10"); // .9
                        }
                    }
                }
            }
        }
    }

    return rval;
}

3
এই ধরনের পার্শ্বীয় চিন্তাভাবনা আমাদের আরও প্রয়োজন! দুর্দান্ত পরামর্শ।
edsko

1
এটি কিছুটা কুৎসিত তবে খুব দ্রুত এবং ব্যবহারিক উপায়ে
বোসাক

1
এটি একটি আকর্ষণীয় পদ্ধতির যা আশ্চর্যজনকভাবে সহজ। স্থান বাঁচাতে আপনি বাইনারি পরিবর্তে একটি অ্যারে অনুসন্ধান করতে পারেন, বা একটি বাইনারি গাছ তৈরি করতে পারেন, তবে আপনার পন্থাটি সম্ভবত সামান্য দ্রুত হবে (ফিরে আসার আগে আপনি স্ট্রিকাটে একক কল ব্যবহার করে স্থান বাঁচাতে পারেন এবং এখন যেখানে ডাকা হয় সেখানে ভেরিও দিতে পারেন)। এছাড়াও আমি 3/10 এবং 7/10 অন্তর্ভুক্ত করতাম তবে এটি কেবল আমারই হবে।
jimhark

1
এই সমাধানটি দ্বারা অনুপ্রাণিত হয়ে আমি একটি সংক্ষিপ্ত (তবে সম্পূর্ণ অপরিবর্তিত) কোড তৈরি করেছি। এটি সহজেই বৃহত পরিসরের ভগ্নাংশ coverাকাতে বাড়ানো যেতে পারে। jsfiddle.net/PdL23/1
দীপক জয়

1
দ্রষ্টব্য যে 1/1000খুব মানবিকভাবে পঠনযোগ্য, তবে উপরের অ্যালগরিদমটি কেবল খুব মোটা 1/10মোটামুটি উত্পাদন করতে পারে ; আমি বিশ্বাস করি যে উন্নতি পদ যার মনুষ্যোচিত পাঠযোগ্য denominators, এক থেকে বাছাই করতে পারেন মধ্যে তৈরি করা যেতে পারে, এবং / অথবা যোগে <, >, <<, >>উপসর্গ পড়তা এর রুক্ষতা একটি ধারণা দিতে।
ভ্লাদর

16

দশমিককে ভগ্নাংশে রূপান্তর করার পিছনে গণিতের ব্যাখ্যা দেওয়ার জন্য এখানে একটি লিঙ্ক রয়েছে:

http://www.webmath.com/dec2fract.html

এবং এটি ভিবি ব্যবহার করে কীভাবে করা যায় তার একটি উদাহরণ ফাংশন (www.freevbcode.com/ShowCode.asp?ID=582 থেকে):

Public Function Dec2Frac(ByVal f As Double) As String

   Dim df As Double
   Dim lUpperPart As Long
   Dim lLowerPart As Long

   lUpperPart = 1
   lLowerPart = 1

   df = lUpperPart / lLowerPart
   While (df <> f)
      If (df < f) Then
         lUpperPart = lUpperPart + 1
      Else
         lLowerPart = lLowerPart + 1
         lUpperPart = f * lLowerPart
      End If
      df = lUpperPart / lLowerPart
   Wend
Dec2Frac = CStr(lUpperPart) & "/" & CStr(lLowerPart)
End Function

(গুগল অনুসন্ধান থেকে: দশমিককে ভগ্নাংশে রূপান্তর করুন, দশমিককে ভগ্নাংশের কোডে রূপান্তর করুন)


2
নোট করুন এই এলগরিদমটি যখন f = n / m হয় তখন Ω (মি) সময় নেয়। এবং এটি অনেক কিছু হতে পারে, এমনকি যদি আপনি এটি হওয়ার ইচ্ছা না করেন (0.66666666667 বিবেচনা করুন)।
einpoklum

10

আপনি প্রতিটি কম্পিউটার বিজ্ঞানী ফ্লোটিং পয়েন্ট এরিথমেটিক সম্পর্কে কী জানতে হবে তা পড়তে চাইতে পারেন ।

আপনাকে একটি বৃহত সংখ্যার দ্বারা গুণ করে কিছু নির্ভুলতা নির্দিষ্ট করতে হবে:

3.141592 * 1000000 = 3141592

তারপরে আপনি একটি ভগ্নাংশ তৈরি করতে পারেন:

3 + (141592 / 1000000)

এবং জিসিডি এর মাধ্যমে হ্রাস করুন ...

3 + (17699 / 125000)

তবে উদ্দেশ্যযুক্ত ভগ্নাংশটি বের করার কোনও উপায় নেই । পরিবর্তে আপনি সর্বদা আপনার কোড জুড়ে ভগ্নাংশ ব্যবহার করতে চাইতে পারেন - যখন আপনি অতিরিক্ত প্রবাহ এড়াতে পারেন তখন ভগ্নাংশ কমিয়ে আনতে ভুলবেন না!


9

দেবিনমুর দ্বারা প্রস্তাবিত ভিবি কোডের পার্ল এবং জাভাস্ক্রিপ্ট সংস্করণগুলি এখানে রয়েছে:

পার্ল:

sub dec2frac {
    my $d = shift;

    my $df  = 1;
    my $top = 1;
    my $bot = 1;

    while ($df != $d) {
      if ($df < $d) {
        $top += 1;
      }
      else {
         $bot += 1;
         $top = int($d * $bot);
      }
      $df = $top / $bot;
   }
   return "$top/$bot";
}

এবং প্রায় অভিন্ন জাভাস্ক্রিপ্ট:

function dec2frac(d) {

    var df = 1;
    var top = 1;
    var bot = 1;

    while (df != d) {
        if (df < d) {
            top += 1;
        }
        else {
            bot += 1;
            top = parseInt(d * bot);
        }
        df = top / bot;
    }
    return top + '/' + bot;
}

9

এসি # বাস্তবায়ন

/// <summary>
/// Represents a rational number
/// </summary>
public struct Fraction
{
    public int Numerator;
    public int Denominator;

    /// <summary>
    /// Constructor
    /// </summary>
    public Fraction(int numerator, int denominator)
    {
        this.Numerator = numerator;
        this.Denominator = denominator;
    }

    /// <summary>
    /// Approximates a fraction from the provided double
    /// </summary>
    public static Fraction Parse(double d)
    {
        return ApproximateFraction(d);
    }

    /// <summary>
    /// Returns this fraction expressed as a double, rounded to the specified number of decimal places.
    /// Returns double.NaN if denominator is zero
    /// </summary>
    public double ToDouble(int decimalPlaces)
    {
        if (this.Denominator == 0)
            return double.NaN;

        return System.Math.Round(
            Numerator / (double)Denominator,
            decimalPlaces
        );
    }


    /// <summary>
    /// Approximates the provided value to a fraction.
    /// http://stackoverflow.com/questions/95727/how-to-convert-floats-to-human-readable-fractions
    /// </summary>
    private static Fraction ApproximateFraction(double value)
    {
        const double EPSILON = .000001d;

        int n = 1;  // numerator
        int d = 1;  // denominator
        double fraction = n / d;

        while (System.Math.Abs(fraction - value) > EPSILON)
        {
            if (fraction < value)
            {
                n++;
            }
            else
            {
                d++;
                n = (int)System.Math.Round(value * d);
            }

            fraction = n / (double)d;
        }

        return new Fraction(n, d);
    }
}


6

সমস্যার অংশটি হ'ল এতগুলি ভগ্নাংশ আসলে ভগ্নাংশ হিসাবে সহজেই ধরা হয় না। যেমন 0.33 1/3 নয়, এটি 33/100। তবে যদি আপনি আপনার প্রাথমিক বিদ্যালয়ের প্রশিক্ষণ মনে রাখেন তবে দশমিক মানগুলি ভগ্নাংশে রূপান্তর করার প্রক্রিয়া রয়েছে তবে বেশিরভাগ দশমিক সংখ্যা 0.33 এ সংরক্ষণ করা হয় না তবে 0.329999999999998 বা এরকম কিছু হতে পারে তাই আপনি যা চান তা আপনাকে দেবার সম্ভাবনা কম।

নিজেকে অনুগ্রহ করুন এবং এটি নিয়ে বিরক্ত করবেন না, তবে আপনার যদি প্রয়োজন হয় তবে আপনি নিম্নলিখিতটি করতে পারেন:

আপনি ভগ্নাংশটি অপসারণ না করা পর্যন্ত মূল মান 10 দিয়ে গুণ করুন। এই নম্বরটি রাখুন, এবং এটি বিভাজক হিসাবে ব্যবহার করুন। তারপরে সাধারণ ডিনোমিনেটর সন্ধান করে একাধিক সরলকরণের কাজ করুন।

সুতরাং 0.4 4-10 হবে। তারপরে আপনি কম মান, সম্ভবত প্রাথমিক সংখ্যা দিয়ে শুরু করে সাধারণ বিভাজকের সন্ধান করবেন। 2 দিয়ে শুরু করে আপনি দেখতে পাবেন যে 2 বিভাগ এবং তলটি বিভাগের মতো একই কিনা তা পরীক্ষা করে উভয় অংকের এবং বিভাজনকে সমানভাবে বিভক্ত করে।

floor(5/2) = 2
5/2 = 2.5

সুতরাং 5 সমানভাবে 2 ভাগ করে না। তারপরে আপনি পরবর্তী নম্বরটি পরীক্ষা করে দেখুন, 3 say

আপনি এটি করার পরে আপনার প্রয়োজন


1
আমি এই শেষ পদক্ষেপের জন্য ইউক্যালিডিয়ান অ্যালগরিদম ব্যবহার করার পরামর্শ দেব
গ্রাফিক্স নূব


4

"আসুন আমরা বলি যে আমাদের 0.33 আছে, আমাদের" 1/3 "আউটপুট করতে হবে।"

"সমাধান" আপনি কী সঠিকতা প্রত্যাশা করবেন? 0.33 1/3 এর সমান নয়। আপনি কীভাবে একটি "ভাল" (সহজেই পড়া) উত্তরটি চিনতে পারবেন?

যাই হোক না কেন, একটি সম্ভাব্য অ্যালগরিদম হতে পারে:

আপনি যদি X / Y ফর্মের নিকটতম ভগ্নাংশটি খুঁজে পাওয়ার আশা করেন যেখানে Y কম হয় 10, তবে আপনি প্রতিটি Y গুণমান এক্স এর জন্য সমস্ত 9 সম্ভাব্য Ys লুপ করতে পারেন এবং তারপরে সর্বাধিক সঠিকটি নির্বাচন করতে পারেন।


3

আমি মনে করি এটির সর্বোত্তম উপায় হ'ল প্রথমে আপনার ভাসমান মানকে একটি আসকি উপস্থাপনায় রূপান্তর করা। সি ++ এ আপনি অস্ট্রিংস্ট্রিম ব্যবহার করতে পারেন বা সিতে, আপনি স্প্রিন্টফ ব্যবহার করতে পারেন। এটি সি ++ এ কীভাবে দেখবে তা এখানে:

ostringstream oss;
float num;
cin >> num;
oss << num;
string numStr = oss.str();
int i = numStr.length(), pow_ten = 0;
while (i > 0) {
    if (numStr[i] == '.')
        break;
    pow_ten++;
    i--;
}
for (int j = 1; j < pow_ten; j++) {
    num *= 10.0;
}
cout << static_cast<int>(num) << "/" << pow(10, pow_ten - 1) << endl;

একটি অনুরূপ পদ্ধতি সোজা সিতে নেওয়া যেতে পারে in

এর পরে আপনাকে পরীক্ষা করে দেখতে হবে যে ভগ্নাংশটি সর্বনিম্ন শর্তে রয়েছে। এই অ্যালগরিদম একটি সুনির্দিষ্ট উত্তর দেবে, অর্থাৎ 0.33 "33/100" আউটপুট দেবে, "1/3" নয়। যাইহোক, 0.4 "4-10" দেয়, যা সর্বনিম্ন শর্তে কমে গেলে "2/5" হয়। এটি এপস্টিনের সমাধানের মতো শক্তিশালী নাও হতে পারে তবে আমি বিশ্বাস করি এটি আরও সোজা।


8 বছর পরে আমি আপনার সমাধানটি পেরিয়ে এসেছি, আমি পরীক্ষা করেছি এবং এটি এখন পর্যন্ত নিখুঁতভাবে কাজ করছে, তবে আপনি বলেছিলেন যে এটি এপস্টাইনের সমাধানের মতো শক্তিশালী নয় এবং আমি কেন আশ্চর্য হয়েছি। যেহেতু আপনার সমাধানটি আরও সহজ, এটি পছন্দ করার সমাধান হওয়া উচিত নয়, তাই যতক্ষণ না এটি কার্যকর হয় ততক্ষণ আমরা কী সহজতম কোডটি করা সম্ভব এবং এটি নিরাপদ নয় ??
এইচবাতালহা

3

আর-তে একটি অন্তর্নির্মিত সমাধান:

library(MASS)
fractions(0.666666666)
## [1] 2/3

এটি একটি অবিরত ভগ্নাংশ পদ্ধতি ব্যবহার করে এবং নির্ভুলতা সামঞ্জস্য করার জন্য optionচ্ছিক cyclesএবং max.denominatorযুক্তি রয়েছে has


এছাড়াও library(numbers)এবং contFrac(0.6666); পছন্দসই স্ট্রিং আউটপুট পেতে:paste(contFrac(0.666, tol=1e-03)$rat, collapse="/")
rbatt

2

আপনি কোন স্তরের ত্রুটি গ্রহণ করতে রাজি তা আপনাকে খুঁজে বের করতে হবে। সমস্ত দশমিক ভগ্নাংশ সাধারণ ভগ্নাংশে হ্রাস পাবে না। আমি সম্ভবত 60-এর মতো একটি সহজেই বিভাজ্য সংখ্যাটি বেছে নেব এবং কতগুলি 60 মুল্যের নিকটতম, তা ভগ্নাংশটি সরল করে ফেলব।


2

আপনি নিম্নলিখিত পদক্ষেপগুলি ব্যবহার করে যে কোনও প্রোগ্রামিং ভাষায় এটি করতে পারেন:

  1. 10 places x দ্বারা গুণিত করুন এবং ভাগ করুন যেখানে সংখ্যা 10 এর দশমিক স্থান অবশিষ্ট নেই তা নিশ্চিত করার জন্য 10 টির শক্তি প্রয়োজন। উদাহরণ: 0.33 কে 10 ^ 2 = 100 দিয়ে এটি 33 করার গুণন করুন এবং 33/100 পেতে এটির সাথে ভাগ করুন
  2. যতক্ষণ না আপনি ফলাফল থেকে পূর্ণসংখ্যার পক্ষে আর না পেয়েছেন ততক্ষণ পর্যন্ত গুণক দ্বারা ফলক ভগ্নাংশের সংখ্যা এবং ডিনোমিনেটর হ্রাস করুন।
  3. ফলস্বরূপ হ্রাস ভগ্নাংশটি আপনার উত্তর হওয়া উচিত।

উদাহরণ: 0.2 = 0.2 x 10 ^ 1/10 ^ 1 = 2/10 = 1/5

সুতরাং, এটি '5 এর 1 অংশ' হিসাবে পড়া যায়


2

একটি সমাধান হ'ল প্রথমে সমস্ত সংখ্যা যুক্তিযুক্ত সংখ্যা হিসাবে সংরক্ষণ করা। যৌক্তিক সংখ্যা গণিতের জন্য গ্রন্থাগার রয়েছে (যেমন জিএমপি )। যদি ওও ভাষা ব্যবহার করে থাকেন তবে আপনি নিজের নম্বর শ্রেণিটি প্রতিস্থাপন করতে কেবল যুক্তিবাদী নম্বর শ্রেণির পাঠাগারটি ব্যবহার করতে পারবেন।

অন্যদের মধ্যে ফিনান্স প্রোগ্রামগুলি নির্ভুল গণনা করতে এবং নির্ভুলতা সংরক্ষণ করতে সক্ষম হওয়ার জন্য এই জাতীয় সমাধানটি ব্যবহার করে যা সাধারণ প্লেট ব্যবহার করে হারিয়ে যেতে পারে।

অবশ্যই এটি অনেক ধীর হবে তাই এটি আপনার পক্ষে ব্যবহারিক নাও হতে পারে। আপনার কতটা গণনা করতে হবে এবং নির্ভুলতা আপনার জন্য কতটা গুরুত্বপূর্ণ তা নির্ভর করে।

a = rational(1);
b = rational(3);
c = a / b;

print (c.asFraction)  --->  "1/3"
print (c.asFloat) ----> "0.333333"

2

ধরা যাক আমাদের 0.33 আছে, আমাদের "1/3" আউটপুট করতে হবে। আমাদের যদি "0.4" থাকে তবে আমাদের "2/5" আউটপুট নিতে হবে।

এটি সাধারণ ক্ষেত্রে ভুল, কারণ 1/3 = 0.3333333 = 0 (3) তদতিরিক্ত, প্রস্তাবিত উপরের সমাধানগুলি থেকে দশমিককে সংজ্ঞায়িত নির্ভুলতার সাথে ভগ্নাংশে রূপান্তর করা যায়, কারণ আউটপুট সবসময় ভগ্নাংশ হয়।

তবে, আমি সূত্রের ভিত্তিতে, অসীম জ্যামিতিক সিরিজের ধারণার ভিত্তিতে অনেকগুলি বিকল্পের সাথে আমার বিস্তৃত ফাংশনটির পরামর্শ দিচ্ছি :

এখানে চিত্র বর্ণনা লিখুন

প্রথমে এই ফাংশনটি স্ট্রিং প্রতিনিধিত্বতে ভগ্নাংশের সময়সীমার সন্ধান করার চেষ্টা করছে। তারপরে বর্ণিত উপরের সূত্রটি প্রয়োগ করা হবে।

যুক্তিযুক্ত নম্বর কোডটি সি # তে স্টিফেন এম ম্যাককেমি যুক্তিযুক্ত সংখ্যা বাস্তবায়নের কাছ থেকে নেওয়া হয়েছে । আমি আশা করি অন্য কোডগুলিতে আমার কোডটি পোর্ট করা খুব কঠিন নয়।

/// <summary>
/// Convert decimal to fraction
/// </summary>
/// <param name="value">decimal value to convert</param>
/// <param name="result">result fraction if conversation is succsess</param>
/// <param name="decimalPlaces">precision of considereation frac part of value</param>
/// <param name="trimZeroes">trim zeroes on the right part of the value or not</param>
/// <param name="minPeriodRepeat">minimum period repeating</param>
/// <param name="digitsForReal">precision for determination value to real if period has not been founded</param>
/// <returns></returns>
public static bool FromDecimal(decimal value, out Rational<T> result, 
    int decimalPlaces = 28, bool trimZeroes = false, decimal minPeriodRepeat = 2, int digitsForReal = 9)
{
    var valueStr = value.ToString("0.0000000000000000000000000000", CultureInfo.InvariantCulture);
    var strs = valueStr.Split('.');

    long intPart = long.Parse(strs[0]);
    string fracPartTrimEnd = strs[1].TrimEnd(new char[] { '0' });
    string fracPart;

    if (trimZeroes)
    {
        fracPart = fracPartTrimEnd;
        decimalPlaces = Math.Min(decimalPlaces, fracPart.Length);
    }
    else
        fracPart = strs[1];

    result = new Rational<T>();
    try
    {
        string periodPart;
        bool periodFound = false;

        int i;
        for (i = 0; i < fracPart.Length; i++)
        {
            if (fracPart[i] == '0' && i != 0)
                continue;

            for (int j = i + 1; j < fracPart.Length; j++)
            {
                periodPart = fracPart.Substring(i, j - i);
                periodFound = true;
                decimal periodRepeat = 1;
                decimal periodStep = 1.0m / periodPart.Length;
                var upperBound = Math.Min(fracPart.Length, decimalPlaces);
                int k;
                for (k = i + periodPart.Length; k < upperBound; k += 1)
                {
                    if (periodPart[(k - i) % periodPart.Length] != fracPart[k])
                    {
                        periodFound = false;
                        break;
                    }
                    periodRepeat += periodStep;
                }

                if (!periodFound && upperBound - k <= periodPart.Length && periodPart[(upperBound - i) % periodPart.Length] > '5')
                {
                    var ind = (k - i) % periodPart.Length;
                    var regroupedPeriod = (periodPart.Substring(ind) + periodPart.Remove(ind)).Substring(0, upperBound - k);
                    ulong periodTailPlusOne = ulong.Parse(regroupedPeriod) + 1;
                    ulong fracTail = ulong.Parse(fracPart.Substring(k, regroupedPeriod.Length));
                    if (periodTailPlusOne == fracTail)
                        periodFound = true;
                }

                if (periodFound && periodRepeat >= minPeriodRepeat)
                {
                    result = FromDecimal(strs[0], fracPart.Substring(0, i), periodPart);
                    break;
                }
                else
                    periodFound = false;
            }

            if (periodFound)
                break;
        }

        if (!periodFound)
        {
            if (fracPartTrimEnd.Length >= digitsForReal)
                return false;
            else
            {
                result = new Rational<T>(long.Parse(strs[0]), 1, false);
                if (fracPartTrimEnd.Length != 0)
                    result = new Rational<T>(ulong.Parse(fracPartTrimEnd), TenInPower(fracPartTrimEnd.Length));
                return true;
            }
        }

        return true;
    }
    catch
    {
        return false;
    }
}

public static Rational<T> FromDecimal(string intPart, string fracPart, string periodPart)
{
    Rational<T> firstFracPart;
    if (fracPart != null && fracPart.Length != 0)
    {
        ulong denominator = TenInPower(fracPart.Length);
        firstFracPart = new Rational<T>(ulong.Parse(fracPart), denominator);
    }
    else
        firstFracPart = new Rational<T>(0, 1, false);

    Rational<T> secondFracPart;
    if (periodPart != null && periodPart.Length != 0)
        secondFracPart =
            new Rational<T>(ulong.Parse(periodPart), TenInPower(fracPart.Length)) *
            new Rational<T>(1, Nines((ulong)periodPart.Length), false);
    else
        secondFracPart = new Rational<T>(0, 1, false);

    var result = firstFracPart + secondFracPart;
    if (intPart != null && intPart.Length != 0)
    {
        long intPartLong = long.Parse(intPart);
        result = new Rational<T>(intPartLong, 1, false) + (intPartLong == 0 ? 1 : Math.Sign(intPartLong)) * result;
    }

    return result;
}

private static ulong TenInPower(int power)
{
    ulong result = 1;
    for (int l = 0; l < power; l++)
        result *= 10;
    return result;
}

private static decimal TenInNegPower(int power)
{
    decimal result = 1;
    for (int l = 0; l > power; l--)
        result /= 10.0m;
    return result;
}

private static ulong Nines(ulong power)
{
    ulong result = 9;
    if (power >= 0)
        for (ulong l = 0; l < power - 1; l++)
            result = result * 10 + 9;
    return result;
}

ব্যবহারের কয়েকটি উদাহরণ রয়েছে:

Rational<long>.FromDecimal(0.33333333m, out r, 8, false);
// then r == 1 / 3;

Rational<long>.FromDecimal(0.33333333m, out r, 9, false);
// then r == 33333333 / 100000000;

ডান অংশ শূন্য অংশ ছাঁটাই আপনার ক্ষেত্রে:

Rational<long>.FromDecimal(0.33m, out r, 28, true);
// then r == 1 / 3;

Rational<long>.FromDecimal(0.33m, out r, 28, true);
// then r == 33 / 100;

ন্যূনতম পিরিয়ড ডিমেস্ট্রেশন:

Rational<long>.FromDecimal(0.123412m, out r, 28, true, 1.5m));
// then r == 1234 / 9999;
Rational<long>.FromDecimal(0.123412m, out r, 28, true, 1.6m));
// then r == 123412 / 1000000; because of minimu repeating of period is 0.1234123 in this case.

শেষে গোলাকার:

Rational<long>.FromDecimal(0.8888888888888888888888888889m, out r));
// then r == 8 == 9;

সবচেয়ে আকর্ষণীয় কেস:

Rational<long>.FromDecimal(0.12345678m, out r, 28, true, 2, 9);
// then r == 12345678 / 100000000;

Rational<long>.FromDecimal(0.12345678m, out r, 28, true, 2, 8);
// Conversation failed, because of period has not been founded and there are too many digits in fraction part of input value.

Rational<long>.FromDecimal(0.12121212121212121m, out r, 28, true, 2, 9));
// then r == 4 / 33; Despite of too many digits in input value, period has been founded. Thus it's possible to convert value to fraction.

অন্যান্য পরীক্ষা এবং কোড প্রত্যেকে গিথুবের আমার ম্যাথফিউশন লাইব্রেরিতে খুঁজে পেতে পারে ।


2

রুবি এর মধ্যে ইতিমধ্যে বিল্ট ইন সলিউশন রয়েছে:

0.33.rationalize.to_s # => "33/100"
0.4.rationalize.to_s # => "2/5"

কারাগারে, অ্যাক্টিভেকর্ড সংখ্যাসূচক বৈশিষ্ট্যগুলিও রূপান্তরিত হতে পারে:

product.size = 0.33
product.size.to_r.to_s # => "33/100"

2

সি ++ তে উত্তর দিন, ধরে নিবেন যে আপনার একটি 'বিগআইএন্ট' শ্রেণি রয়েছে, যা সীমাহীন-আকারের পূর্ণসংখ্যা সঞ্চয় করতে পারে।

পরিবর্তে আপনি 'স্বাক্ষরবিহীন দীর্ঘ দীর্ঘ' ব্যবহার করতে পারেন তবে এটি কেবল নির্দিষ্ট মানগুলির জন্যই কাজ করবে।

void GetRational(double val)
{
    if (val == val+1) // Inf
        throw "Infinite Value";
    if (val != val) // NaN
        throw "Undefined Value";

    bool sign = false;
    BigInt enumerator = 0;
    BigInt denominator = 1;

    if (val < 0)
    {
        val = -val;
        sign = true;
    }

    while (val > 0)
    {
        unsigned int intVal = (unsigned int)val;
        val -= intVal;
        enumerator += intVal;
        val *= 2;
        enumerator *= 2;
        denominator *= 2;
    }

    BigInt gcd = GCD(enumerator,denominator);
    enumerator /= gcd;
    denominator /= gcd;

    Print(sign? "-":"+");
    Print(enumerator);
    Print("/");
    Print(denominator);

    // Or simply return {sign,enumerator,denominator} as you wish
}

বিটিডাব্লু, গেটর্যাশনাল (০.০) "+ ০/১" ফিরিয়ে দেবে, যাতে আপনি এই কেসটি আলাদাভাবে পরিচালনা করতে চান।

পিএস: আমি এই কোডটি কয়েক বছরের জন্য আমার নিজের 'রেশনালমনম' ক্লাসে ব্যবহার করে আসছি এবং এটি পুরোপুরি পরীক্ষা করা হয়েছে।


আপনার উদাহরণটি 1.333333 এর মতো মানগুলি ভেঙে যাচ্ছে বলে মনে হচ্ছে .. এটি মানটি খোঁজার চেষ্টা করে খুব দীর্ঘ লুপে চলে যায় এবং কাজ করে বলে মনে হয় না ... অন্যান্য সাধারণ মান যেমন 1.25
অ্যাডামস্কি

@ অ্যাডামস্কি: ধন্যবাদ whileলুপের "রূপান্তর" সময়কালের আকার দ্বারা আবদ্ধ হয় double, যা সাধারণত b৪ বিট 64 সুতরাং এটি ইনপুট ( val) এর প্রাথমিক মানের উপর নির্ভর করে না । GCDফাংশন, তবে, এই মান উপর নির্ভর করে, যদিও এটি সাধারণত প্রশংসনীয় দ্রুত একটি সমাধান-র দিকে এগোয় না। আপনি কি এই ফাংশনটি সঠিকভাবে প্রয়োগ করেননি তা সম্ভব?
বারাক মনোস

@ অ্যাডামস্কি: এছাড়াও, আমি উত্তরের শুরুতে যেমনটি উল্লেখ করেছি, আপনি যদি এর unsigned long longপরিবর্তে ব্যবহার করেন BigIntতবে তা অবশ্যই প্রতিটি ইনপুট মানের জন্য সঠিক ফলাফল দেয় না ... তবে সেই পরিস্থিতিতেও কোডটি নয় "খুব দীর্ঘ লুপে যেতে" অনুমিত হয়।
বারাক মানস

হ্যাঁ হ্যাঁ, এটি পুরোপুরি সম্ভব, আমি যে জিসিডি ফাংশনটি ব্যবহার করছিলাম সেটি হ'ল জুস লাইব্রেরি বিগইন্টেগার শ্রেণীর একটি অংশ। তথ্যের জন্য ধন্যবাদ!
অ্যাডামস্কি

@Adamski: তাই এটা না ইন্দ্রিয় যে GCDফাংশন সঠিকভাবে বাস্তবায়িত হয়নি। কোডটি দীর্ঘ সময়ের জন্য whileলুপ চলাকালীন সময়ে বা তার পরে চলে কিনা আপনি কি পরীক্ষা করে দেখেছেন? এর পিছনে কী আছে তা দেখতে আমি 1.33333 এর মান পরীক্ষা করব। ধন্যবাদ।
বারাক মানস

2

আয়ান রিচার্ডস / জন কেনেডি এই অ্যালগরিদমটি কেবল সুন্দর ভগ্নাংশই দেয় না, এটি গতির দিক থেকেও খুব ভাল সম্পাদন করে। এই উত্তরটি আমার দ্বারা নেওয়া হিসাবে সি # কোড is

এটি doubleNaN এবং +/- অনন্তের মতো বিশেষ মানগুলি বাদে সমস্ত মানকে পরিচালনা করতে পারে, যা প্রয়োজন হলে আপনাকে যোগ করতে হবে।

এটি a new Fraction(numerator, denominator)। আপনার নিজের ধরণের দ্বারা প্রতিস্থাপন করুন।

আরও উদাহরণস্বরূপ মান এবং অন্যান্য অ্যালগরিদমের সাথে তুলনা করার জন্য, এখানে যান

public Fraction RealToFraction(double value, double accuracy)
{
    if (accuracy <= 0.0 || accuracy >= 1.0)
    {
        throw new ArgumentOutOfRangeException("accuracy", "Must be > 0 and < 1.");
    }

    int sign = Math.Sign(value);

    if (sign == -1)
    {
        value = Math.Abs(value);
    }

    // Accuracy is the maximum relative error; convert to absolute maxError
    double maxError = sign == 0 ? accuracy : value * accuracy;

    int n = (int) Math.Floor(value);
    value -= n;

    if (value < maxError)
    {
        return new Fraction(sign * n, 1);
    }

    if (1 - maxError < value)
    {
        return new Fraction(sign * (n + 1), 1);
    }

    double z = value;
    int previousDenominator = 0;
    int denominator = 1;
    int numerator;

    do
    {
        z = 1.0 / (z - (int) z);
        int temp = denominator;
        denominator = denominator * (int) z + previousDenominator;
        previousDenominator = temp;
        numerator = Convert.ToInt32(value * denominator);
    }
    while (Math.Abs(value - (double) numerator / denominator) > maxError && z != (int) z);

    return new Fraction((n * denominator + numerator) * sign, denominator);
}

এই অ্যালগরিদমের দ্বারা প্রত্যাবর্তিত মানসমূহ উদাহরণ:

Accuracy: 1.0E-3      | Richards                     
Input                 | Result           Error       
======================| =============================
   3                  |       3/1          0         
   0.999999           |       1/1         1.0E-6     
   1.000001           |       1/1        -1.0E-6     
   0.50 (1/2)         |       1/2          0         
   0.33... (1/3)      |       1/3          0         
   0.67... (2/3)      |       2/3          0         
   0.25 (1/4)         |       1/4          0         
   0.11... (1/9)      |       1/9          0         
   0.09... (1/11)     |       1/11         0         
   0.62... (307/499)  |       8/13        2.5E-4     
   0.14... (33/229)   |      16/111       2.7E-4     
   0.05... (33/683)   |      10/207      -1.5E-4     
   0.18... (100/541)  |      17/92       -3.3E-4     
   0.06... (33/541)   |       5/82       -3.7E-4     
   0.1                |       1/10         0         
   0.2                |       1/5          0         
   0.3                |       3/10         0         
   0.4                |       2/5          0         
   0.5                |       1/2          0         
   0.6                |       3/5          0         
   0.7                |       7/10         0         
   0.8                |       4/5          0         
   0.9                |       9/10         0         
   0.01               |       1/100        0         
   0.001              |       1/1000       0         
   0.0001             |       1/10000      0         
   0.33333333333      |       1/3         1.0E-11    
   0.333              |     333/1000       0         
   0.7777             |       7/9         1.0E-4     
   0.11               |      10/91       -1.0E-3     
   0.1111             |       1/9         1.0E-4     
   3.14               |      22/7         9.1E-4     
   3.14... (pi)       |      22/7         4.0E-4     
   2.72... (e)        |      87/32        1.7E-4     
   0.7454545454545    |      38/51       -4.8E-4     
   0.01024801004      |       2/195       8.2E-4     
   0.99011            |     100/101      -1.1E-5     
   0.26... (5/19)     |       5/19         0         
   0.61... (37/61)    |      17/28        9.7E-4     
                      | 
Accuracy: 1.0E-4      | Richards                     
Input                 | Result           Error       
======================| =============================
   0.62... (307/499)  |     299/486      -6.7E-6     
   0.05... (33/683)   |      23/476       6.4E-5     
   0.06... (33/541)   |      33/541        0         
   1E-05              |       1/99999     1.0E-5     
   0.7777             |    1109/1426     -1.8E-7     
   3.14... (pi)       |     333/106      -2.6E-5     
   2.72... (e)        |     193/71        1.0E-5     
   0.61... (37/61)    |      37/61         0         

1

আপনার দুটি মূল সমস্যা রয়েছে যা এটিকে শক্ত করে তুলবে:

1) ভাসমান বিন্দু হুবহু উপস্থাপনা নয় যার অর্থ আপনার যদি "x / y" এর একটি ভগ্নাংশ থাকে যার ফলস্বরূপ "জেড" এর মান হয় তবে আপনার ভগ্নাংশ অ্যালগরিদম "x / y" ব্যতীত অন্য কোনও ফলাফল ফিরে আসতে পারে।

2) যৌক্তিক তুলনায় অনন্ত অনেকগুলি অযৌক্তিক সংখ্যা রয়েছে। যৌক্তিক সংখ্যাটি এমন একটি যা ভগ্নাংশ হিসাবে উপস্থাপিত হতে পারে। অযৌক্তিক সত্তা যা পারে না।

তবে, সস্তা ধরণের উপায়ে, যেহেতু ভাসমান পয়েন্টের সীমাবদ্ধতা যথাযথতা রয়েছে, তাই আপনি সর্বদা এটিকে কোনও উপদলের রূপ হিসাবে উপস্থাপন করতে পারেন। (আমি মনে করি...)


4
একটি float (অথবা ডবল) হয় ভগ্নাংশ। এর ডিনোমিনেটর 2 এর শক্তি That's
ইরিকসন

1

উপরের কোডটি সম্পন্ন করে এএস 3 এ রূপান্তর করেছে

public static function toFrac(f:Number) : String
    {
        if (f>1)
        {
            var parte1:int;
            var parte2:Number;
            var resultado:String;
            var loc:int = String(f).indexOf(".");
            parte2 = Number(String(f).slice(loc, String(f).length));
            parte1 = int(String(f).slice(0,loc));
            resultado = toFrac(parte2);
            parte1 *= int(resultado.slice(resultado.indexOf("/") + 1, resultado.length)) + int(resultado.slice(0, resultado.indexOf("/")));
            resultado = String(parte1) +  resultado.slice(resultado.indexOf("/"), resultado.length)
            return resultado;
        }
        if( f < 0.47 )
            if( f < 0.25 )
                if( f < 0.16 )
                    if( f < 0.13 )
                        if( f < 0.11 )
                            return "1/10";
                        else
                            return "1/9";
                    else
                        if( f < 0.14 )
                            return "1/8";
                        else
                            return "1/7";
                else
                    if( f < 0.19 )
                        return "1/6";
                    else
                        if( f < 0.22 )
                            return "1/5";
                        else
                            return "2/9";
            else
                if( f < 0.38 )
                    if( f < 0.29 )
                        return "1/4";
                    else
                        if( f < 0.31 )
                            return "2/7";
                        else
                            return "1/3";
                else
                    if( f < 0.43 )
                        if( f < 0.40 )
                            return "3/8";
                        else
                            return "2/5";
                    else
                        if( f < 0.44 )
                            return "3/7";
                        else
                            return "4/9";
        else
            if( f < 0.71 )
                if( f < 0.60 )
                    if( f < 0.56 )
                        return "1/2";
                    else
                        if( f < 0.57 )
                            return "5/9";
                        else
                            return "4/7";
                else
                    if( f < 0.63 )
                        return "3/5";
                    else
                        if( f < 0.66 )
                            return "5/8";
                        else
                            return "2/3";
            else
                if( f < 0.80 )
                    if( f < 0.74 )
                        return "5/7";
                    else
                        if(f < 0.78 )
                            return "3/4";
                        else
                            return "7/9";
                else
                    if( f < 0.86 )
                        if( f < 0.83 )
                            return "4/5";
                        else
                            return "5/6";
                    else
                        if( f < 0.88 )
                            return "6/7";
                        else
                            if( f < 0.89 )
                                return "7/8";
                            else
                                if( f < 0.90 )
                                    return "8/9";
                                else
                                    return "9/10";
    }

ধন্যবাদ, আমি এটি ডেলফির জন্য ব্যবহার করেছি, সমস্ত কোঁকড়ানো
পিটার টার্নার

1

এখানে জাভাস্ক্রিপ্টে একটি দ্রুত এবং নোংরা বাস্তবায়ন যা একটি জন্তু শক্তি পদ্ধতির ব্যবহার করে। মোটেও অনুকূলিত নয়, এটি ভগ্নাংশের পূর্বনির্ধারিত পরিসরের মধ্যে কাজ করে: http://jsfiddle.net/PdL23/1/

/* This should convert any decimals to a simplified fraction within the range specified by the two for loops. Haven't done any thorough testing, but it seems to work fine.

I have set the bounds for numerator and denominator to 20, 20... but you can increase this if you want in the two for loops.

Disclaimer: Its not at all optimized. (Feel free to create an improved version.)
*/

decimalToSimplifiedFraction = function(n) {

    for(num = 1; num < 20; num++) {  // "num" is the potential numerator
        for(den = 1; den < 20; den++) {  // "den" is the potential denominator
            var multiplyByInverse = (n * den ) / num;

            var roundingError = Math.round(multiplyByInverse) - multiplyByInverse;

            // Checking if we have found the inverse of the number, 
            if((Math.round(multiplyByInverse) == 1) && (Math.abs(roundingError) < 0.01)) {
                return num + "/" + den;
            }
        }
    }
};

//Put in your test number here.
var floatNumber = 2.56;

alert(floatNumber + " = " + decimalToSimplifiedFraction(floatNumber));

এটি জেপিএসের ব্যবহৃত পদ্ধতির দ্বারা অনুপ্রাণিত হয়।


0

যেহেতু অনেক লোক বলেছেন যে আপনি সত্যিই কোনও ভাসমান বিন্দুকে কোনও ভগ্নাংশে রূপান্তর করতে পারবেন না (যদি এর চূড়ান্ত ঠিক মতো না হয় 25)। অবশ্যই আপনি ভগ্নাংশের বৃহত অ্যারেটির জন্য কিছু প্রকারের চেহারা তৈরি করতে পারেন এবং যে ফলাফলটি আপনি সন্ধান করছেন তা উত্পাদন করার জন্য এক ধরণের অস্পষ্ট যুক্তি ব্যবহার করতে পারেন। আবার এটি যদিও সঠিক হবে না এবং আপনার ডিনোমিনিটারটি কতটা বড় হতে চান তার নীচের সীমানা নির্ধারণ করতে হবে।

.32 <x <.34 = 1/3 বা এর মতো কিছু।



0

আমি একটি অ্যানোমরফিজম ব্যবহার করে একটি বিশেষভাবে মার্জিত হাস্কেল সমাধান জুড়ে এসেছি। এটি পুনরাবৃত্তি-প্রকল্পগুলির প্যাকেজের উপর নির্ভর করে ।

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE FlexibleContexts    #-}

import           Control.Applicative   (liftA2)
import           Control.Monad         (ap)
import           Data.Functor.Foldable
import           Data.Ratio            (Ratio, (%))

isInteger :: (RealFrac a) => a -> Bool
isInteger = ((==) <*>) (realToFrac . floor)

continuedFraction :: (RealFrac a) => a -> [Int]
continuedFraction = liftA2 (:) floor (ana coalgebra)
    where coalgebra x
              | isInteger x = Nil
              | otherwise = Cons (floor alpha) alpha
                  where alpha = 1 / (x - realToFrac (floor x))

collapseFraction :: (Integral a) => [Int] -> Ratio a
collapseFraction [x]    = fromIntegral x % 1
collapseFraction (x:xs) = (fromIntegral x % 1) + 1 / collapseFraction xs

-- | Use the nth convergent to approximate x
approximate :: (RealFrac a, Integral b) => a -> Int -> Ratio b
approximate x n = collapseFraction $ take n (continuedFraction x)

যদি আপনি এটিকে GCI এ চেষ্টা করে দেখেন তবে এটি সত্যিই কাজ করে!

λ:> approximate pi 2
22 % 7
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.