HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Immutable Fraction class

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
immutableclassfraction

Problem

Inspired by this question: Fraction class implemented in Objective-C, I have written what I feel is an improved version of the Fraction class in Objective-C.

As per the tips in this answer, the class is immutable (and a mutable subclass might eventually happen). Besides improving on the existing functionality and changing to an immutable object, I also added the necessary methods for comparing fractions to other objects, other fractions, and importantly adding the compare: method so that the fractions can be sorted!

Fraction.h

#import 

@interface Fraction : NSObject
/*
    An immutable class for representing and doing math 
        with rational numbers represented as fractions 
        with a numerator and denominator part.
 */

@property (readonly) NSInteger numerator;
@property (readonly) NSInteger denominator;

- (instancetype)initWithNumerator:(NSInteger)numerator 
                      denominator:(NSInteger)denominator;

+ (instancetype)notANumber;
+ (instancetype)zero;
+ (instancetype)one;
+ (instancetype)fractionWithInteger:(NSInteger)integer;
+ (instancetype)fractionWithReciprocalOf:(NSInteger)integer;
+ (instancetype)fractionWithNumerator:(NSInteger)numerator 
                          denominator:(NSInteger)denominator;
+ (instancetype)fractionWithFraction:(Fraction *)fraction;

// TODO: init with floating points.

- (instancetype)fractionByAddingFraction:(Fraction *)fraction;
- (instancetype)fractionBySubtractingFraction:(Fraction *)fraction;
- (instancetype)fractionByMultiplyingByFraction:(Fraction *)fraction;
- (instancetype)fractionByDividingByFraction:(Fraction *)fraction;

- (instancetype)reduced;
- (instancetype)reciprocal;

- (double)doubleValue;
- (float)floatValue;
- (int)intValue;
- (long)longValue;
- (NSInteger)integerValue;

- (BOOL)isEqualToFraction:(Fraction *)fraction;
- (NSComparisonResult)compare:(Fraction *)fraction;

@end

@interface NSNumber(Fraction)

+ (instancetype)numberWithFraction:(Fraction *)fraction;

@end


`

Solution

One big issue I have with your code is that all of of your comparisons are based off of the fraction's double value. This can lead to many bugs down the line that result in questions like this.

To fix this: you can do one of two things: define or pass an epsilon (such as .00001) to be used for comparison.

Or even better, use the denominator and numerator to compare fractions.

To do so, I would utilize memoization (to make this performant for repeated calls on the same fraction), and to to store the fraction in reduced form. Then you do a simple comparison on the reduced form like so:

  • Fraction 1: \$\dfrac{x}{y}\$



  • Fraction 2: \$\dfrac{a}{b}\$



Compare \$xb\$ to \$ay\$:

  • if \$xb > ay\$, Fraction 1 is bigger.



  • if \$x*b



  • if \$xb = ay\$, Fraction 1 is equal to Fraction 2.

Context

StackExchange Code Review Q#56936, answer score: 4

Revisions (0)

No revisions yet.