2012-04-19 59 views
1

作爲計算器應用程序的一部分,我試圖用sigma符號實現用法。但是,打印出來的結果總是小數,其餘部分並不重要。我只是想把小數改成小數。將Objective-C中的小數轉換爲小數(有理數)?

我已經有減少的功能,我在從這樣的小數得到的問題:它「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; 

} 
+0

我想象中的目標是「字符串表示」雖然對於代表一小部分的數據類型的名稱往往是「理性的」(見[有理數](HTTP:// en.wikipedia.org/wiki/Rational_number))。使用它可以幫助改進搜索,例如google給了我[RCRationalNumber](http://rosettacode.org/wiki/Arithmetic/Rational/Objective-C),它有'initWithDouble'。 – 2012-04-19 17:56:40

+0

這是一個*相關的*問題:http://stackoverflow.com/questions/5552537/convert-decimal-to-fraction-in-objective-c顯示如何在C中完成它。但是,我沒有關閉一個複製品,因爲可能會有「更多Obj-C方式」。然而,接受的答案在鏈接上相當不錯。 – 2012-04-19 18:02:29

+0

在詢問之前,我對上述問題進行了研究,這正是我所問的原因,我希望看到「更多obj-c方式」 – JTApps 2012-04-19 18:03:35

回答

5

發現了這一點自己。我所做的是將分子和分母乘以1000000(回想小數點看起來像.96875/1),使其看起來像96875/100000

然後,我用這種降低方法,使其最低條款:

-(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 
0

我發現一個相當好的方式做了一段時間後,雖然我不記得在哪裏從。無論如何,它的工作原理遞歸這樣的(這是僞代碼,而不是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。

0

試試這個:

-(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]; 
}