在 Objective-C 中将小数转换为分数?

发布于 2024-10-30 14:53:45 字数 600 浏览 2 评论 0原文

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

更新:5/13/2011

嗯,我让它显示 7 1/16,但是数学上的一些东西关闭了。因为即使改变被除的值,它也不会改变 1/16。我这里哪里出错了?如果有人真的能让这个正常工作,请完整地发布它是如何完成的。这应该很简单,但实际上并不简单,而且太耗时。请完整地发布它是如何完成的。谢谢。

更新: 如果这个答案对您不起作用,请查看我的其他帖子,这有效! 将小数转换为分数

I am trying to take everything after the decimal and display it as a fraction. Couldn't find much for objective-c on how to accomplish this. I am using double for my formatting of variables, not sure if that would matter or not. This is how I am formatting for output of my answer:[theTextField setText:[NSString stringWithFormat:@"%f''", (myVariable)]]; This displays ok as decimal, but would really like it as a whole number and fraction (ie.) 7 1/2 instead of 7.5000. Thank you in advanced!

Update:5/13/2011

Well, I got it to display 7 1/16, but something with the math is off. Because it won't change from 1/16 even by changing the values that are getting divided. Where am I going wrong here? If anyone can actually get this to work correctly please post fully how its done. This is something that should be simple but isn't and way too time consuming. Please post fully how it is done. Thanks.

Update:
If this answer isn't working for you check out my other post, this works! Convert decimals to fractions

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

折戟 2024-11-06 14:53:45

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

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

如何将浮点数转换为人类可读的分数?

(具体来说这个答案 具有实际的 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”
有关为什么会发生这种情况的一些信息,请参阅相关问题的答案:如何将浮点数转换为人类可读的分数?

Objective-C uses pure C for basically all primitive mathematical operations.

This being said you'll find all necessary information (along with C code) in the answers of this other question:

How to convert floats to human-readable fractions?

(Specifically this answer featuring actual C code.)

Here is a quick c function wrapper of said algorithm:

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

Calling it like this:

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);

Prints this:

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

Last but not least let's see how we get our newly crafted fraction into out text field:

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

Expected output: "7 1/2", actual output: "7 499/999"
For some info on why this can happen see this answer to a related question: How to convert floats to human-readable fractions?

怕倦 2024-11-06 14:53:45

我编写了代码将小数转换为尽可能小的分数。这效果非常好。

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

I have written code to convert decimal to its lowest possible fraction. This works perfectly well.

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

call method as:

[self floatToFraction:2.5];  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文