且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-12-10 12:00:59

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

这就是说你会在这个问题的答案中找到所有必要的信息(以及C代码):

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



(具体 C代码为特色。)



这是一个快速的c函数包装的算法:

  typedef struct {
长提名人;
长分母;
双重错误;
}分数;
$ b $ *
*给出实数的有理逼近
* David Eppstein / UC Irvine / 8 Aug 1993
*
* Formella,2008年5月
* Regexident函数包装,2011年4月
*
* usage:fractionFromReal(double realNumber,long maxDenominator)
* realNumber:实数到约$ b如果x = a1 + 1 /(a2 + 1 /(a3 + 1 /(b)),基于连续分数理论,$ b * maxDieominator:允许的最大分母
*
* a4 + ...)))
*那么通过截断这个系列
*(在上一项中进行了一些调整)可以找到***逼近。
*
*注意这个分数可以作为矩阵
*(a1 1)(a2 1)(a3 1)...
*(1 0)(1 0)(1 0)
*而不是保留连续分式项的序列,
*我们只保留这些矩阵的最后部分积。
* /
分数fractionFromReal(double realNumber,long maxDenominator){
double atof();
int atoi();
void exit();

long m [2] [2];
双startx;
long ai;

startx = realNumber;

//初始化矩阵:
m [0] [0] = m [1] [1] = 1;
m [0] [1] = m [1] [0] = 0;

//循环查找条件直到denom变得太大:
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;
$ b $ if(realNumber ==(double)ai){
// AF:除零
break;
}

realNumber = 1 /(realNumber - (double)ai);

if(realNumber>(double)0x7FFFFFFF){
// AF:表示失败
break;
}
}

ai =(maxDominator -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])};

$ / code>

像这样调用:

  double aReal = 123.45; 
long maxDenominator = 42;
分数aFraction = fractionFromReal(aReal,maxDenominator);
printf(Real%.3f - > fraction =>%ld /%ld,error:%.3f\\\

aReal,
aFraction.nominator,
aFraction.derorator,
aFraction.error);

打印此:

  Real 123.450  - >分数=> 3827/31,错误:-0.002 

最后但并非最不重要的让我们看看我们如何得到我们新制作的分数进入出文本字段:

  double myVariable = 7.5; 
long maxDenominator = 1000; //样本值
分数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

有关这种情况发生的一些信息,请参阅相关问题的解答:如何将浮动转换为可读的分数?


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

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?