Archived
1

Reorganized File Structure

Added Documentation
This commit is contained in:
Kim Wittenburg
2014-12-12 00:39:30 +01:00
parent c367b1dbe8
commit 8f1f730358
90 changed files with 1270 additions and 1216 deletions

View File

@@ -0,0 +1,112 @@
//
// MPFunctionValue.m
// MathPad
//
// Created by Kim Wittenburg on 11.10.14.
// Copyright (c) 2014 Kim Wittenburg. All rights reserved.
//
#import "MPElementaryFunctionTerm.h"
#import "MPParsedExpression.h"
#import "MPPowerFunction.h"
#import "MPProductTerm.h"
#import "MPToken.h"
#import "MPExpression.h"
#import "MPMathRules.h"
@implementation MPElementaryFunctionTerm {
NSDecimalNumber *(^_function)(NSDecimalNumber *);
}
- (instancetype)initWithFunctionIdentifier:(NSString *)function
term:(MPTerm *)term
{
self = [super init];
if (self) {
NSAssert(function != nil, @"function must not be nil.");
NSAssert(term != nil, @"term must not be nil.");
double (*func)(double);
BOOL takesArc = NO;
BOOL returnsArc = NO;
if ([function isEqualToString:@"sin"]) {
func = &sin;
takesArc = YES;
} else if ([function isEqualToString:@"cos"]) {
func = &cos;
takesArc = YES;
} else if ([function isEqualToString:@"tan"]) {
func = &tan;
takesArc = YES;
} else if ([function isEqualToString:@"asin"] || [function isEqualToString:@"arcsin"]) {
func = &asin;
returnsArc = YES;
} else if ([function isEqualToString:@"acos"] || [function isEqualToString:@"arccos"]) {
func = &acos;
returnsArc = YES;
} else if ([function isEqualToString:@"atan"] || [function isEqualToString:@"arctan"]) {
func = &atan;
returnsArc = YES;
} else if ([function isEqualToString:@"lg"] || [function isEqualToString:@"log"]) {
func = &log10;
} else if ([function isEqualToString:@"ln"]) {
func = &log;
} else {
NSAssert(true, @"function must be one of (sin, cos, tan, asin, acos, atan, lg, log, ln).");
}
[self setFunction:func
takesArcValue:takesArc
returnsArcValue:returnsArc];
_term = term;
}
return self;
}
- (void)setFunction:(double (*)(double))function
takesArcValue:(BOOL)takesArc
returnsArcValue:(BOOL)returnsArc
{
id __weak weakSelf = self;
_function = ^(NSDecimalNumber *value){
if (takesArc) {
value = [weakSelf convertToRadiantsIfNecessary:value];
}
NSDecimalNumber *returnValue = [[NSDecimalNumber alloc] initWithDouble:function(value.doubleValue)];
if (returnsArc) {
returnValue = [weakSelf convertToDegreesIfNecessary:returnValue];
}
return returnValue;
};
}
- (NSDecimalNumber *)convertToRadiantsIfNecessary:(NSDecimalNumber *)degrees
{
if ([MPMathRules sharedRules].isUsingDegrees) {
// * M_PI / 180
return [[degrees decimalNumberByMultiplyingBy:[[NSDecimalNumber alloc] initWithDouble:M_PI]] decimalNumberByDividingBy:[[NSDecimalNumber alloc] initWithInteger:180]];
} else {
return degrees;
}
}
- (NSDecimalNumber *)convertToDegreesIfNecessary:(NSDecimalNumber *)radiants
{
if ([MPMathRules sharedRules].isUsingDegrees) {
// * 180 / M_PI
return [[radiants decimalNumberByMultiplyingBy:[[NSDecimalNumber alloc] initWithInteger:180]] decimalNumberByDividingBy:[[NSDecimalNumber alloc] initWithDouble:M_PI]];
} else {
return radiants;
}
}
- (NSDecimalNumber *)doEvaluation:(NSError *__autoreleasing *)error
{
NSDecimalNumber *value = [self.term evaluate:error];
if (!value) {
return nil;
}
return _function(value);
}
@end