我试图取小数点后的所有内容并将其显示为分数。找不到有关如何实现这一点的Objective-c。我正在使用double
来格式化变量,不确定这是否重要。这就是我为我的答案输出格式化的方式:[theTextField setText:[NSString stringWithFormat:@"%f''", (myVariable)]];
这显示为十进制确定,但是真的希望它作为整数和分数(即。)7 1/2而不是7.5000。先谢谢你了!
更新:5/13/2011
好吧,我得到它显示7 1/16,但数学的东西是关闭的。因为即使通过改变分割的值,它也不会从1/16变化。我在哪里错了?如果有人能够真正使这个工作正常,请完整地发布它是如何完成的。这应该是简单的,但不是太耗时。请完整地发布它是如何完成的。谢谢。
更新: 如果这个答案不起作用,请查看我的其他帖子,这有效! Convert decimals to fractions
答案 0 :(得分:8)
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?
答案 1 :(得分:6)
我编写了将十进制转换为最低分数的代码。这非常有效。
-(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];