【问题标题】:Convert decimal to fraction (rational number) in Objective C?在Objective C中将小数转换为分数(有理数)?
【发布时间】:2012-04-19 17:53:01
【问题描述】:

作为计算器应用程序的一部分,我正在尝试使用 sigma 表示法来实现用途。但是,它打印出来的结果始终是小数,其余的并不重要。我只是想将小数更改为分数。

我已经有了 reduce 函数,我遇到的问题是从这样的小数:'0.96875' 到它的小数,'31/32'

谢谢!

PS:我已经研究了几乎所有的东西,而对于我的生活,我无法弄清楚这一点。在这一点上,我所需要的只是如何从中取出小数,然后我可以减少它。

这是我的 reduce 方法:

    -(void)reduce {

    int u = numerator;
    int v = denominator;
    int temp;

    while (v != 0) {
        temp = u % v;
        u = v;
        v = temp;
    }

    numerator /= u;
    denominator /= u;

}

【问题讨论】:

  • 我想目标是“字符串表示”,尽管表示分数的数据类型的名称通常是“Rational”(参见Rational Number)。使用它可能有助于优化搜索,例如谷歌给了我RCRationalNumber,其中有initWithDouble
  • 这是一个 related 问题:stackoverflow.com/questions/5552537/… 显示了如何在 C 中执行此操作。但是,我不会作为重复项关闭,因为可能存在“更多 Obj -C 方式”。但是,接受的答案非常适合链接。
  • 我在问之前查看了上面的那个问题,这正是我问的原因,我想看看“更多的 obj-c 方式”

标签: objective-c math rational-numbers


【解决方案1】:

这是我自己发现的。我所做的是将分子和分母乘以 1000000(回想一下小数点看起来像 .96875/1),所以它看起来像 96875/100000

然后,我用这个 reduce 方法把它降到最低:

    -(void)reduce {

    int u = numerator;
    int v = denominator;
    int temp;

    while (v != 0) {
        temp = u % v;
        u = v;
        v = temp;
    }

    numerator /= u;
    denominator /= u;

}

最后,我用打印方法把它变成了分数形式:

//In the .h
@property int numerator, denominator, mixed;
-(void)print;

//In the .m       
@synthesize numerator, denominator, mixed;

-(void)print {
    if (numerator > denominator) {
        //Turn fraction into mixed number
        mixed = numerator/denominator;
        numerator -= (mixed * denominator);
        NSLog(@"= %i %i/%i", mixed, numerator, denominator);
    } else if (denominator != 1) {
        //Print fraction normally
        NSLog(@"= %i/%i", numerator, denominator);
    } else {
        //Print as integer if it has a denominator of 1
        NSLog(@"= %i", numerator);
    }
}

得到了我想要的输出:

31/32

【讨论】:

    【解决方案2】:

    不久前我发现了一个相当不错的方法,虽然我不记得从哪里来的。无论如何,它像这样递归地工作(这是伪代码,而不是 C):

    function getRational(float n)
      let i = floor(n); (the integer component of n)
      let j = n - i;
      if j < 0.0001 (use abritrary precision threshold here), return i/1
      let m/n = getRational(1 / j)
      return ((i * m) + n) / m
    

    例如,以 3.142857 为起点。

    i = 3
    j = 0.142857
    m/n = getRational(7)
      i = 7
      j = 0
      return 7/1
    m/n = 7/1
    return ((3*7)+1) / 7 = 22/7
    

    或者更复杂的例子,1.55:

    i = 1
    j = 0.55
    m/n = getRational(1.81818181)
      i = 1
      j = 0.81818181
      m/n = getRational(1.22222222)
        i = 1
        j = 0.22222222
        m/n = getRational(4.5)
          i = 4
          j = 0.5
          m/n = getRational(2)
            i = 2
            j = 0
            return 2/1
          m/n = 2/1
          return ((4*2)+1)/2 = 9/2
        m/n = 9/2
        return ((1*9)+2)/9 = 11/9
      m/n = 11/9
      return ((1*11)+9)/11) = 20/11
    m/n = 20/11
    return ((1*20)+11)/20 = 31/20
    

    我用 PI 试过一次。它会持续一段时间,但如果您将阈值设置为 0.01,它只会在返回 355/113 之前下降一些递归。

    有一点问题,如果它返回时下降得太深,你最终可能会得到太大的整数;除了将精度阈值设置为相当宽松的值(例如 0.01)之外,我还没有真正研究过允许这种情况的好方法。

    【讨论】:

      【解决方案3】:

      试试这个:

      -(NSString *)convertToFraction:(CGFloat)floatValue{
          double tolerance = 1.0E-6;
          CGFloat h1 = 1;
          CGFloat h2 = 0;
          CGFloat k1 = 0;
          CGFloat k2 = 1;
          CGFloat b = floatValue;
          do{
              CGFloat a = floor(b);
              CGFloat aux = h1;
              h1 = a*h1+h2;
              h2 = aux;
              aux = k1;
              k1 = a*k1+k2;
              k2 = aux;
              b = 1/(b-a);
          }while (ABS(floatValue-h1/k1) > floatValue*tolerance) ;
      
          return k1 > 1 ?  [NSString stringWithFormat:@"%.0f/%.0f",h1,k1] : [NSString stringWithFormat:@"%.0f",h1];
      }
      

      【讨论】:

        猜你喜欢
        • 2011-07-29
        • 2014-12-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多