为什么在创建将两个分数对象相加时缺少我的整数?

Why is my whole number missing when creating adding two fraction objects together?

更新:这个问题显然是数学问题,如果有人对如何将 wholeNumber 添加到计算方法中有任何意见,我们将不胜感激。

我在这里很困惑。我正在编写一个 objective c 程序并创建一个分数对象。

在我的分数对象中,我有加法、减法、乘法等方法。一切正常,但由于某种原因,在我调用我的数学方法后,我丢失了要显示的整数。如果我为我的分数输入 5/4 并调用 print 方法,我得到 1 1/4,但是当我调用 add 方法并发送另一个分数对象 5/4(所以我添加 5/4 + 5/4) ,将它存储到一个结果对象中并打印,当我应该得到 2 1/2 时只得到 1/2。我是不是忽略了这里的某些东西,或者在我的数学函数中存储了一些错误的东西?显然我是 objective-c 的新手。为什么我会丢失此输出中的整数?它应该是 2 1/2 而不是我只得到 1/2


    Fraction *Fraction1 = [[Fraction alloc] init];// fraction object
    Fraction *Fraction2 = [[Fraction alloc] init];// fraction object
    Fraction *result;

        
    [Fraction1 setTo: 5 over: 4];
    [Fraction2 setTo: 5 over: 4];
        
    [Fraction1 print];
    [Fraction2 print];
    result = [Fraction1 add: Fraction2];
    
    //display the fraction
    NSLog (@"the value of myFraction is: ");
      [result print];

我的主力


#import "fraction.h"

@implementation Fraction
    
@synthesize numerator;
@synthesize denominator;
@synthesize wholeNumber;


-(Fraction *) add:(Fraction *)fraction{
    Fraction *result =[[Fraction alloc] init];

    result.numerator = (numerator * fraction.denominator) + (fraction.numerator * denominator);
    result.denominator = denominator * fraction.denominator;
    
    
    [result reduce];
    return result;
}

-(Fraction *) divide:(Fraction *)fraction {
    Fraction *result =[[Fraction alloc] init];
    result.numerator = numerator * fraction.denominator;
    result.denominator = denominator * fraction.numerator;
   
    [result reduce];
    return result;
}

-(Fraction *) multiply:(Fraction *)fraction{
    Fraction *result =[[Fraction alloc] init];
    result.numerator = numerator * fraction.numerator;
    result.denominator = denominator * fraction.denominator;

    [self reduce];
    return result;
}

-(Fraction *) subtract:(Fraction *) fraction{
    Fraction *result =[[Fraction alloc] init];
    result.numerator = (numerator * fraction.denominator) - (fraction.numerator * denominator);
    result.denominator =  denominator  * fraction.denominator;
    
    [result reduce];
    
    return result;
}

-(void) reduce {
    int u = numerator;
    int v = denominator;
    int temp;
    
    while (v != 0) {
        temp = u % v;
        u = v;
        v = temp;
    }
    numerator /= u;
    denominator /= u;
}

-(void) print{
    
    if (numerator > denominator && numerator % denominator == 0) {
        int wholeNumber = numerator / denominator;
        NSLog(@"The whole number is %i", wholeNumber);
    } else if ( numerator > denominator) {
        wholeNumber = numerator / denominator;
        numerator = numerator % denominator;
        NSLog(@"Mixed fraction %i %i/%i", wholeNumber, numerator, denominator);
    } else {
        NSLog(@"%i/%i", numerator, denominator);
    }
}

-(void) setTo:(int) n over: (int) d {
    numerator = n;
    denominator = d;
}
        
-(int) numerator{
    return numerator;
}
        
-(void) setNumerator: (int) n{
    numerator = n;
}

-(void) setDenominator: (int) d{
    denominator = d;
}

-(int) denominator{
    return denominator;
}
        
-(double) convertToNum{
    if (denominator !=0)
        return (double) numerator/denominator;
    else
        return NAN;
}

-(int) wholeNum {
    return wholeNumber;
}

-(void) setWholeNum: (int) n {
    wholeNumber = n;
}

@end

分数class


-(Fraction *) add:(Fraction *)fraction{
    Fraction *result =[[Fraction alloc] init];

    result.numerator = (numerator * fraction.denominator) + (fraction.numerator * denominator);
    result.denominator = denominator * fraction.denominator;
    
    
    [result reduce];
    return result;
}

最后是我的添加方法

输出如下

 Mixed fraction 1 1/4
 Mixed fraction 1 1/4
 the value of myFraction is:
 1/2
Program ended with exit code: 0

'''

reduce 中的循环之前添加 wholeNumber += v ? u / v : 0;

你的数学方法不考虑 wholenumber 值,只考虑 numeratordenominator,所以每次你做数学运算时 wholenumber 值在 result 中是 0.

您的 reduce 也忽略了 wholenumber 值,但它至少保留了它(因此 1 8/4 减少到 1 2/1 而不是 3)。

当您调用 print 时,那是您设置 wholenumber 的唯一一次,任何未来的操作都会将值归零(数学)或忽略它(减少)。

HTH

评论后补遗

Is there a better way to represent these mathematically?

用整数对 numeratordenominatorfraction 表示一个值作为 混合数 与整数的三元组 整数分子分母 不影响 数学 accuracy/result/etc.

但是,与整数范围无限的数学不同,计算机倾向于使用有限范围的整数进行算术运算——例如64 位架构上的类型 unsigned int 只能表示 0 到 9,223,372,036,854,775,807 (2^64 - 1) 范围内的值,虽然相当大但并非无限制。

这样做的一个结果是最好对不可约形式的分数进行运算;即永远不要将 1/2 表示为 2,305,843,009,213,693,952/4,611,686,018,427,387,904;因为这有助于将每个整数保持在可用的有限范围内。

另一个考虑是是否允许假分数,其中分子大于分母[=85] =] 对,例如4/3;或对这些使用 混合数字,例如1 1/3。后者可以增加可以表示的值的范围,例如1 1/9,223,372,036,854,775,807 不能表示为假分数 9,223,372,036,854,775,808/9,223,372,036,854,775,807 使用 64-但无符号整数,因为分子太大,会导致溢出错误。

所以如何表示分数取决于目标:

  • 如果分数的分子和分母可能总是很小的值,那么你可以允许不正确的分数和分数,并在运算后减少结果;你可能会避免溢出等

  • 如果目标是提供通用分数以尽可能避免溢出并提供可表示值的最大范围,那么您可以选择混合数字表示并减少 during 操作.

  • 如果目标是允许不正确的和未缩减的分数,并且无论计算成本如何都适用于任何值,您可以选择第一个选项结合任意精度整数 library/framework 并避免以这种方式出现溢出和范围问题 – 至少在您的计算机内存不足之前...

维基百科页面 Fraction数学 方面的良好开端,但它并未涵盖计算机算术有限的问题。

(请注意,为简单起见,上面的示例使用无符号数作为整数范围的基础,分数当然可以是负数,因此将使用正常的带符号整数 [尽管分母可以是无符号的]).

If I try adding values like wholeNumber = denominator / numerator (to the add method) but it will only work mathematically 1/2 the time.

这仅仅意味着您在实施过程中遇到了错误,您如何代表您的价值观不是问题。如果您将带分数相加 a b/c & d e/f 那么,忽略不正确和未减少的分数问题,总和为:

wholenumber = a + d
numerator = b * f + e * c
denominator = c * f

如果您无法让您的实现正常工作,请提出一个新问题来解释您的表示、算法、哪里出了问题、您尝试了什么等等,毫无疑问会有人帮助您。