1 | //
|
2 | // JKBigDecimal.m
|
3 | // JKBigInteger
|
4 | //
|
5 | // Created by Midfar Sun on 5/4/15.
|
6 | // Copyright (c) 2015 Midfar Sun. All rights reserved.
|
7 | //
|
8 |
|
9 | // Licensed under the MIT License
|
10 |
|
11 | #import "JKBigDecimal.h"
|
12 |
|
13 | @implementation JKBigDecimal
|
14 | @synthesize bigInteger, figure;
|
15 |
|
16 | + (BOOL)supportsSecureCoding {
|
17 | return YES;
|
18 | }
|
19 |
|
20 | - (id)init
|
21 | {
|
22 | return [self initWithString:@"0"];
|
23 | }
|
24 |
|
25 | - (id)initWithString:(NSString *)string
|
26 | {
|
27 | self = [super init];
|
28 | if (self) {
|
29 | figure = 0;
|
30 | if ([string containsString:@"."]) {
|
31 | NSRange range = [string rangeOfString:@"."];
|
32 | figure = string.length-range.location-range.length;
|
33 | string = [string stringByReplacingCharactersInRange:range withString:@""];
|
34 | }
|
35 | bigInteger = [[JKBigInteger alloc] initWithString:string];
|
36 | }
|
37 | return self;
|
38 | }
|
39 |
|
40 | + (id)decimalWithString:(NSString *)string
|
41 | {
|
42 | return [[JKBigDecimal alloc] initWithString:string];
|
43 | }
|
44 |
|
45 | -(id)initWithBigInteger:(JKBigInteger *)i figure:(NSInteger)f
|
46 | {
|
47 | self = [super init];
|
48 | if (self) {
|
49 | bigInteger = i;
|
50 | figure = f;
|
51 | }
|
52 | return self;
|
53 | }
|
54 |
|
55 | - (instancetype)initWithCoder:(NSCoder *)decoder
|
56 | {
|
57 | self = [super init];
|
58 | if (self) {
|
59 | bigInteger = [[JKBigInteger alloc] initWithCoder:decoder];
|
60 | figure = [decoder decodeInt32ForKey:@"JKBigDecimalFigure"];
|
61 | }
|
62 | return self;
|
63 | }
|
64 | -(void)encodeWithCoder:(NSCoder *)encoder
|
65 | {
|
66 | [bigInteger encodeWithCoder:encoder];
|
67 | [encoder encodeInteger:figure forKey:@"JKBigDecimalFigure"];
|
68 | }
|
69 |
|
70 | - (id)add:(JKBigDecimal *)bigDecimal
|
71 | {
|
72 | NSInteger maxFigure = 0;
|
73 | if (figure>=bigDecimal.figure) {
|
74 | maxFigure = figure;
|
75 | NSInteger exponent = maxFigure-bigDecimal.figure;
|
76 | JKBigInteger *mInteger = [[JKBigInteger alloc] initWithString:@"10"];
|
77 | JKBigInteger *newInteger = [mInteger pow:(unsigned int)exponent];
|
78 | bigDecimal.bigInteger = [bigDecimal.bigInteger multiply:newInteger];
|
79 | bigDecimal.figure = maxFigure;
|
80 |
|
81 | }else{
|
82 | maxFigure = bigDecimal.figure;
|
83 | NSInteger exponent = maxFigure-figure;
|
84 | JKBigInteger *mInteger = [[JKBigInteger alloc] initWithString:@"10"];
|
85 | JKBigInteger *newInteger = [mInteger pow:(unsigned int)exponent];
|
86 | bigInteger = [bigInteger multiply:newInteger];
|
87 | figure = maxFigure;
|
88 |
|
89 | }
|
90 | JKBigInteger *newBigInteger = [bigInteger add:bigDecimal.bigInteger];
|
91 | JKBigDecimal *newBigDecimal = [[JKBigDecimal alloc] initWithBigInteger:newBigInteger figure:maxFigure];
|
92 | return newBigDecimal;
|
93 | }
|
94 |
|
95 | - (id)subtract:(JKBigDecimal *)bigDecimal
|
96 | {
|
97 | NSInteger maxFigure = 0;
|
98 | if (figure>=bigDecimal.figure) {
|
99 | maxFigure = figure;
|
100 | NSInteger exponent = maxFigure-bigDecimal.figure;
|
101 | JKBigInteger *mInteger = [[JKBigInteger alloc] initWithString:@"10"];
|
102 | JKBigInteger *newInteger = [mInteger pow:(unsigned int)exponent];
|
103 | bigDecimal.bigInteger = [bigDecimal.bigInteger multiply:newInteger];
|
104 | bigDecimal.figure = maxFigure;
|
105 |
|
106 | }else{
|
107 | maxFigure = bigDecimal.figure;
|
108 | NSInteger exponent = maxFigure-figure;
|
109 | JKBigInteger *mInteger = [[JKBigInteger alloc] initWithString:@"10"];
|
110 | JKBigInteger *newInteger = [mInteger pow:(unsigned int)exponent];
|
111 | bigInteger = [bigDecimal.bigInteger multiply:newInteger];
|
112 | figure = maxFigure;
|
113 |
|
114 | }
|
115 | JKBigInteger *newBigInteger = [bigInteger subtract:bigDecimal.bigInteger];
|
116 | JKBigDecimal *newBigDecimal = [[JKBigDecimal alloc] initWithBigInteger:newBigInteger figure:maxFigure];
|
117 | return newBigDecimal;
|
118 | }
|
119 |
|
120 | - (id)multiply:(JKBigDecimal *)bigDecimal
|
121 | {
|
122 | NSInteger totalFigure = figure+bigDecimal.figure;
|
123 | JKBigInteger *newBigInteger = [bigInteger multiply:bigDecimal.bigInteger];
|
124 | JKBigDecimal *newBigDecimal = [[JKBigDecimal alloc] initWithBigInteger:newBigInteger figure:totalFigure];
|
125 | return newBigDecimal;
|
126 | }
|
127 |
|
128 | - (id)divide:(JKBigDecimal *)bigDecimal
|
129 | {
|
130 | NSInteger totalFigure = figure-bigDecimal.figure;
|
131 | if (totalFigure<0) {
|
132 | NSInteger exponent = -totalFigure;
|
133 | totalFigure=0;
|
134 | JKBigInteger *mInteger = [[JKBigInteger alloc] initWithString:@"10"];
|
135 | JKBigInteger *newInteger = [mInteger pow:(unsigned int)exponent];
|
136 | bigInteger = [bigInteger multiply:newInteger];
|
137 | }
|
138 | JKBigInteger *newBigInteger = [bigInteger divide:bigDecimal.bigInteger];
|
139 | JKBigDecimal *newBigDecimal = [[JKBigDecimal alloc] initWithBigInteger:newBigInteger figure:totalFigure];
|
140 | return newBigDecimal;
|
141 | }
|
142 |
|
143 | - (id)remainder:(JKBigDecimal *)bigDecimal
|
144 | {
|
145 | NSInteger totalFigure = figure-bigDecimal.figure;
|
146 | if (totalFigure<0) {
|
147 | NSInteger exponent = -totalFigure;
|
148 | totalFigure=0;
|
149 | JKBigInteger *mInteger = [[JKBigInteger alloc] initWithString:@"10"];
|
150 | JKBigInteger *newInteger = [mInteger pow:(unsigned int)exponent];
|
151 | bigInteger = [bigInteger multiply:newInteger];
|
152 | }
|
153 | JKBigInteger *newBigInteger = [bigInteger remainder:bigDecimal.bigInteger];
|
154 | JKBigDecimal *newBigDecimal = [[JKBigDecimal alloc] initWithBigInteger:newBigInteger figure:bigDecimal.figure];
|
155 | return newBigDecimal;
|
156 | }
|
157 |
|
158 | //- (NSArray *)divideAndRemainder:(JKBigDecimal *)bigInteger
|
159 | //{
|
160 | //
|
161 | //}
|
162 |
|
163 | -(NSComparisonResult) compare:(JKBigDecimal *)other {
|
164 | JKBigDecimal *tens = [[JKBigDecimal alloc] initWithString:@"10"];
|
165 | JKBigInteger *scaledNum;
|
166 | JKBigInteger *scaledCompareTo;
|
167 |
|
168 | if (figure > other.figure){
|
169 | tens = [tens pow:(int)figure];
|
170 | } else {
|
171 | tens = [tens pow:(int)other.figure];
|
172 | }
|
173 | //scale my value to integer value
|
174 | scaledNum = [[JKBigInteger alloc] initWithString:[[self multiply:tens] stringValue]];
|
175 | //scale other value to integer
|
176 | scaledCompareTo = [[JKBigInteger alloc] initWithString:[[other multiply:tens] stringValue]];
|
177 | NSComparisonResult compareBigInteger = [scaledNum compare:scaledCompareTo];
|
178 | return compareBigInteger;
|
179 | }
|
180 |
|
181 | - (id)pow:(unsigned int)exponent
|
182 | {
|
183 | NSInteger totalFigure = figure*exponent;
|
184 | JKBigInteger *newBigInteger = [bigInteger pow:exponent];
|
185 | JKBigDecimal *newBigDecimal = [[JKBigDecimal alloc] initWithBigInteger:newBigInteger figure:totalFigure];
|
186 | return newBigDecimal;
|
187 | }
|
188 |
|
189 | - (id)negate
|
190 | {
|
191 | JKBigInteger *newBigInteger = [bigInteger negate];
|
192 | JKBigDecimal *newBigDecimal = [[JKBigDecimal alloc] initWithBigInteger:newBigInteger figure:figure];
|
193 | return newBigDecimal;
|
194 | }
|
195 |
|
196 | - (id)abs
|
197 | {
|
198 | JKBigInteger *newBigInteger = [bigInteger abs];
|
199 | JKBigDecimal *newBigDecimal = [[JKBigDecimal alloc] initWithBigInteger:newBigInteger figure:figure];
|
200 | return newBigDecimal;
|
201 | }
|
202 |
|
203 | - (NSString *)stringValue
|
204 | {
|
205 | NSString *string = [bigInteger stringValue];
|
206 | if (figure==0) {
|
207 | return string;
|
208 | }
|
209 | NSMutableString *mString = [NSMutableString stringWithString:string];
|
210 | NSInteger newFigure = string.length-figure;
|
211 | while (newFigure<=0) {
|
212 | [mString insertString:@"0" atIndex:0];
|
213 | newFigure++;
|
214 | }
|
215 | [mString insertString:@"." atIndex:newFigure];
|
216 | return mString;
|
217 | }
|
218 |
|
219 | - (NSString *)description
|
220 | {
|
221 | return [self stringValue];
|
222 | }
|
223 |
|
224 | @end
|