【问题标题】:Convert decimal to fraction in Objective-C?在Objective-C中将小数转换为分数?
【发布时间】:2011-07-29 23:32:27
【问题描述】:

我正在尝试将小数点后的所有内容显示为分数。在如何实现这一点上,objective-c 找不到太多东西。我使用double 来格式化变量,不确定这是否重要。这就是我为我的答案输出格式化的方式:[theTextField setText:[NSString stringWithFormat:@"%f''", (myVariable)]]; 这显示为十进制,但我真的希望它作为一个整数和分数(即)7 1/2 而不是 7.5000。提前谢谢你!

更新:2011 年 5 月 13 日

好吧,我让它显示 7 1/16,但是数学上的东西是关闭的。因为即使通过更改被划分的值,它也不会从 1/16 改变。我在哪里错了?如果有人真的可以让它正常工作,请完全发布它是如何完成的。这应该是简单的,但不是太耗时。请完整发布它是如何完成的。谢谢。

更新: 如果此答案对您不起作用,请查看我的其他帖子,这有效! Convert decimals to fractions

【问题讨论】:

    标签: iphone objective-c xcode formatting


    【解决方案1】:

    Objective-C 基本上使用纯 C 语言进行所有原始数学运算。

    也就是说,您将在其他问题的答案中找到所有必要的信息(以及 C 代码):

    How to convert floats to human-readable fractions?

    (特别是this answer 具有实际的C 代码。)

    这里是该算法的快速 c 函数包装器:

    typedef struct {
        long nominator;
        long denominator;
        double error;
    } Fraction;
    
    /*
     * Find rational approximation to given real number
     * David Eppstein / UC Irvine / 8 Aug 1993
     *
     * With corrections from Arno Formella, May 2008
     * Function wrapper by Regexident, April 2011
     *
     * usage: fractionFromReal(double realNumber, long maxDenominator)
     *   realNumber: is real number to approx
     *   maxDenominator: 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.
     */
    Fraction fractionFromReal(double realNumber, long maxDenominator) {
       double atof();
       int atoi();
       void exit();
    
       long m[2][2];
       double startx;
       long ai;
    
       startx = realNumber;
    
       // 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)realNumber) + m[1][1] <= maxDenominator) {
           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 (realNumber == (double)ai) {
               // AF: division by zero
               break;
           }
    
           realNumber = 1 / (realNumber - (double)ai);
    
           if (realNumber > (double)0x7FFFFFFF) {
               // AF: representation failure
               break;
           }
       }
    
       ai = (maxDenominator - 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];
       return (Fraction) { .nominator = m[0][0], .denominator = m[1][0], .error = startx - ((double)m[0][0] / (double)m[1][0]) };
    }
    

    这样称呼它:

    double aReal = 123.45;
    long maxDenominator = 42;
    Fraction aFraction = fractionFromReal(aReal, maxDenominator);
    printf("Real %.3f -> fraction => %ld/%ld, error: %.3f\n",
           aReal,
           aFraction.nominator,
           aFraction.denominator,
           aFraction.error);
    

    打印这个:

    Real 123.450 -> fraction => 3827/31, error: -0.002
    

    最后但同样重要的是,让我们看看我们如何将新制作的分数放入文本字​​段:

    double myVariable = 7.5;
    long maxDenominator = 1000; //sample value
    Fraction myFraction = fractionFromReal(abs(myVariable - (NSInteger)myVariable), maxDenominator);
    [theTextField setText:[NSString stringWithFormat:@"%d %d/%d", (NSInteger)myVariable, myFraction.nominator, myFraction.denominator]];
    

    预期输出:"7 1/2",实际输出:"7 499/999"
    有关为什么会发生这种情况的一些信息,请参阅相关问题的答案:How to convert floats to human-readable fractions?

    【讨论】:

    • 你试过用这个吗?它给出了 4 个警告并使应用程序崩溃,不确定需要修复什么。这会放在 .m 文件中,对吧?
    • 为我工作。尝试用"int main (int ac, const char * av[]) {" 替换"main(ac, av) int ac; char ** av; {",它应该可以正常工作。
    • 通过将名称从 main 更改为 convert 并在末尾添加 return 0; 使其工作。谢谢
    • 调用此函数的最佳方法是什么?在我的代码的实际数学中,或者在使用上述代码显示文本字段的答案时?
    • 这在很大程度上取决于您之后对分数的处理方式。将实数转换为分数并不总是无损的。 (如我的示例输出所示)因此,您通常应该在显示之前将转换作为最后一步,以确保最佳准确性。顺便说一句,为方便起见,我在答案中添加了一个快速函数包装器。
    【解决方案2】:

    我已经编写了将十进制转换为可能的最低分数的代码。这工作得很好。

    -(int)gcdForNumber1:(int) m andNumber2:(int) n 
    {
        while( m!= n) // execute loop until m == n
        {
            if( m > n)
                m= m - n; // large - small , store the results in large variable<br> 
            else
                n= n - m;
        }
        return ( m); // m or n is GCD
    }
    
    
    -(int)tenRaisedTopower:(int)decimalLength { 
        int answer = 10; 
        while (decimalLength!= 1) {
            answer *= 10;
            decimalLength -- ; 
        } 
        return answer;
    }
    
    -(void)floatToFraction:(float)decimalNumber 
    {
        NSString *decimalString = [NSString stringWithFormat:@"%f", decimalNumber];
        NSArray *components = [decimalString componentsSeparatedByString:@"."];
        int decimalLength = [[components objectAtIndex:1] length];
        int n = [self tenRaisedTopower:decimalLength];
        int m = [[components objectAtIndex:1] intValue];
        int gcd = [self gcdForNumber1:m andNumber2:n];
        int numer = m/gcd;
        int deno = n/gcd;
        int fractionnumer = ([[components objectAtIndex:0] intValue] * deno) + numer;
        NSLog(@"answer>>%d/%d", fractionnumer, deno);
    }
    

    调用方法为:

    [self floatToFraction:2.5];  
    

    【讨论】:

    • 您应该熟悉 StackOverflow 代码格式:stackoverflow.com/editing-help。特别值得注意的是,您不需要为换行符使用 HTML &lt;br&gt; 标签。看看我是如何编辑你的答案的。
    • 当您不使用正整数时会出现问题。模块化方法应该用于任何整数。 - (int)gcdForNumber1:(int) m andNumber2:(int) n { while( n!=0) { int temp = n; n = m % 温度; m = 温度; } 返回(米); }
    猜你喜欢
    • 1970-01-01
    • 2014-12-31
    • 1970-01-01
    • 1970-01-01
    • 2016-08-30
    • 2015-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多