xcode 在Objective-C中将小数转换为分数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5552537/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Convert decimal to fraction in Objective-C?
提问by Jason
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!
我试图取小数点后的所有内容并将其显示为分数。关于如何实现这一目标,找不到太多关于objective-c 的信息。我正在使用double
我的变量格式,不确定这是否重要。这就是我为我的答案输出格式化的方式:[theTextField setText:[NSString stringWithFormat:@"%f''", (myVariable)]];
这可以显示为十进制,但真的很喜欢它作为整数和分数(即)7 1/2 而不是 7.5000。先谢谢了!
Update:5/13/2011
更新: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.
好吧,我让它显示了 7 1/16,但是数学上的东西关闭了。因为即使改变被分割的值,它也不会从 1/16 改变。我哪里出错了?如果有人真的可以让它正常工作,请完整发布它是如何完成的。这应该很简单,但不是太耗时。请完整发布它是如何完成的。谢谢。
Update: If this answer isn't working for you check out my other post, this works! Convert decimals to fractions
更新:如果这个答案对你不起作用,请查看我的另一篇文章,这是有效的!将小数转换为分数
采纳答案by Regexident
Objective-C uses pure C for basically all primitive mathematical operations.
Objective-C 使用纯 C 语言进行基本上所有的原始数学运算。
This being said you'll find all necessary information (along with C code) in the answers of this other question:
话虽如此,您将在另一个问题的答案中找到所有必要的信息(以及 C 代码):
How to convert floats to human-readable fractions?
(Specifically this answerfeaturing actual C code.)
(特别是这个答案具有实际的C 代码。)
Here is a quick c function wrapper of said algorithm:
这是所述算法的快速 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]) };
}
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?
预期输出:"7 1/2"
,实际输出:"7 499/999"
有关为什么会发生这种情况的一些信息,请参阅相关问题的答案:如何将浮点数转换为人类可读的分数?
回答by JJQ
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];