#import <Foundation/Foundation.h>
/**
* 分数
*/
@interface CDFraction : NSObject
{
//类的成员变量(字段)
NSInteger _num; //分子
NSInteger _den; //分母
}
/**
* 用指定的分子和分母创建分数对象
*
* @param num 分子
* @param den 分母
*
* @return 分数对象的指针
*/
+ (instancetype) fractionWithNum:(NSInteger) num andDen: (NSInteger) den;
/**
* 用指定的字符串创建分数对象
*
* @param str 分数的字符串表达式
*
* @return 分数对象的指针
*/
+ (instancetype) fractionWithString:(NSString *) str;
/**
* 用指定的有理数(小数)创建分数对象
*
* @param value 有理数(小数)
*
* @return 分数对象的指针
*/
+ (instancetype) fractionWithRational:(double) value;
/**
* 加法
*
* @param other 另一个分数对象
*
* @return 两个分数相加的结果
*/
//instancetype类型就相当于CDFraction *类型
- (CDFraction *) add:(CDFraction *) other;
/**
* 减法
*
* @param other 另一个分数对象
*
* @return 两个分数相减的结果
*/
- (CDFraction *) sub:(CDFraction *) other;
/**
* 乘法
*
* @param other 另一个分数对象
*
* @return 两个分数相乘的结果
*/
- (CDFraction *) mul:(CDFraction *) other;
/**
* 除法
*
* @param other 另一个分数对象
*
* @return 两个分数相除的结果
*/
- (CDFraction *) div:(CDFraction *) other;
@end
#import "CDFraction.h"
//计算x和y的最大公约数的函数
NSInteger gcd(NSInteger x, NSInteger y)
{
if (x > y) {
return gcd(y, x);
}
else if (y % x !=0) {
return gcd(y % x, x);
}
else {
return x;
}
}
@implementation CDFraction
//初始化成员变量
- (instancetype)initWithNum:(NSInteger) num andDen:(NSInteger) den
{
if (den == 0) {
@throw [NSException exceptionWithName:@"分数初始化异常" reason:@"分数的分母不能为0" userInfo:nil];
}
if (self = [super init]) {
_num = num;
_den = den;
}
return [self normalize];
}
//初始化类方法
+ (instancetype)fractionWithNum:(NSInteger)num andDen:(NSInteger)den
{
return [[self alloc] initWithNum:num andDen:den];
}
//重写父类的description方法
- (NSString *)description
{
if (_den == 1) {
return [NSString stringWithFormat:@"(%ld)", _num];
}
return [NSString stringWithFormat:@"%@%ld/%ld%@", _num <0 ? @"(" : @"", _num, _den, _num < 0 ? @")" : @""];
}
//级联编程(开火车式的编程)
//strlen(strcat(strcpy(s1, s2),s3));
//化简
- (instancetype) simplify
{
if (_num == 0) {
_den =1;
}
else {
NSUInteger x = _num <0 ? -_num : _num;
NSUInteger y = _den <0 ? -_den : _den;
NSInteger factor = gcd(x, y);
_num /= factor;
_den /= factor;
}
return self;
}
//正规化(如果分母有负号,将负号放到分子上;如果分子分母都有负号,去掉负号)
- (CDFraction *) normalize
{
if (_den < 0) {
_den = -_den;
_num = -_num;
}
return self;
}
//除法运算
- (CDFraction *)div:(CDFraction *)other
{
return [[[CDFraction fractionWithNum:_num * other->_den andDen:_den * other->_num] normalize] simplify];
}
//乘法运算
- (CDFraction *)mul:(CDFraction *)other
{
return [[[CDFraction fractionWithNum:_num * other->_num andDen:_den * other->_den] normalize] simplify];
}
//减法运算
- (CDFraction *)sub:(CDFraction *)other
{
return [[[CDFraction fractionWithNum:_num * other->_den - _den * other->_num andDen:_den * other->_den] normalize] simplify];
}
//加法运算
- (CDFraction *)add:(CDFraction *)other
{
return [[[CDFraction fractionWithNum:_num * other->_den + _den * other->_num andDen:_den * other->_den] normalize] simplify];
}
//小数转换为分数
+ (instancetype)fractionWithRational:(double)value
{
return [self fractionWithNum:(NSInteger)(value *10000) andDen:10000];
}
//字符串转为分数
+ (instancetype)fractionWithString:(NSString *)str
{
NSArray * strsArray = [str componentsSeparatedByString:@"/"];
if (strsArray.count == 2) {
return [self fractionWithNum:[[strsArray firstObject] integerValue] andDen:[[strsArray lastObject] integerValue]];
}
else {
@throw [NSException exceptionWithName:@"分数初始化异常" reason:@"无效的字符串表达式" userInfo:nil];
}
}
@end
#import <Foundation/Foundation.h>
#import "CDFraction.h"
int main(int argc,const char * argv[]) {
@autoreleasepool {
CDFraction * f1 = [CDFractionfractionWithNum:2andDen:-3];
CDFraction * f2 = [CDFractionfractionWithString:@"1/2"];
CDFraction * f3 = [CDFractionfractionWithRational:0.234];
NSLog(@"%@+%@=%@", f1, f2, [f1add:f2]);
NSLog(@"%@-%@=%@", f1, f2, [f1sub:f2]);
NSLog(@"%@×%@=%@", f1, f2, [f1mul:f3]);
NSLog(@"%@÷%@=%@", f1, f2, [f1div:f3]);
// 运行结果
// 2015-12-14 18:45:03.077 class15121401[4304:254308] (-2/3)+1/2=(-1/6)
// 2015-12-14 18:45:03.078 class15121401[4304:254308] (-2/3)-1/2=(-7/6)
// 2015-12-14 18:45:03.078 class15121401[4304:254308] (-2/3)×1/2=(-39/250)
// 2015-12-14 18:45:03.078 class15121401[4304:254308] (-2/3)÷1/2=(-1000/351)
}
return 0;
}