1 /* Interface of NSDecimalNumber class
2    Copyright (C) 1998 Free Software Foundation, Inc.
3 
4    Written by:  Richard Frith-Macdonald <richard@brainstorm.co.uk>
5    Created: November 1998
6 
7    This file is part of the GNUstep Base Library.
8 
9    This library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 2 of the License, or (at your option) any later version.
13 
14    This library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public
20    License along with this library; if not, write to the Free
21    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22    Boston, MA 02110 USA.
23    */
24 
25 #ifndef __NSDecimalNumber_h_GNUSTEP_BASE_INCLUDE
26 #define __NSDecimalNumber_h_GNUSTEP_BASE_INCLUDE
27 #import	<GNUstepBase/GSVersionMacros.h>
28 
29 #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
30 
31 #import	<Foundation/NSObject.h>
32 #import	<Foundation/NSDecimal.h>
33 #import	<Foundation/NSValue.h>
34 
35 #if	defined(__cplusplus)
36 extern "C" {
37 #endif
38 
39 @class	NSDecimalNumber;
40 
41 /**
42  *  This protocol encapsulates information about how an [NSDecimalNumber]
43  *  should round and process exceptions.  Usually you can just create objects
44  *  of the [NSDecimalNumberHandler] class, which implements this protocol, but
45  *  if you don't want to use that class you can create your own implementing
46  *  it.
47  */
48 @protocol	NSDecimalNumberBehaviors
49 
50 /**
51  *  <p>Specifies behavior when, in the course of applying method to leftOperand
52  *  and rightOperand, an [NSDecimalNumber] instance encounters given error.</p>
53  *  <p>error has four possible constant values:</p>
54  *  <deflist>
55  *  <term><code>NSCalculationLossOfPrecision</code></term>
56  *  <desc>The number can't be represented in 38 significant digits.</desc>
57  *  <term><code>NSCalculationOverflow</code></term>
58  *  <desc>The number is too large to represent.</desc>
59  *  <term><code>NSCalculationUnderflow</code></term>
60  *  <desc>The number is too small to represent.</desc>
61  *  <term><code>NSCalculationDivideByZero</code></term>
62  *  <desc>The caller tried to divide by 0.</desc>
63  *  </deflist>
64  *
65  *  <p>Behavior on error can be one of the following:</p>
66  *  <list>
67  *  <item>Raise an exception.</item>
68  *  <item>Return nil.  The calling method will return its value as though no
69  *    error had occurred. If error is
70  *    <code>NSCalculationLossOfPrecision</code>, method will return an
71  *    imprecise value, constrained to 38 significant digits.  If error is
72  *    <code>NSCalculationUnderflow</code> or
73  *    <code>NSCalculationOverflow</code>, method will return
74  *    <code>NSDecimalNumber</code>'s <code>notANumber</code>. You shouldn't
75  *    return nil if error is <code>NSDivideByZero</code>.
76  *  </item>
77  *  <item>Correct the error and return a valid <code>NSDecimalNumber</code>.
78  *    The calling method will use this as its own return value.</item>
79  *  </list>
80  */
81 - (NSDecimalNumber*) exceptionDuringOperation: (SEL)method
82 					error: (NSCalculationError)error
83 				  leftOperand: (NSDecimalNumber*)leftOperand
84 				 rightOperand: (NSDecimalNumber*)rightOperand;
85 
86 /**
87  *  Specifies how [NSDecimalNumber]'s <code>decimalNumberBy...</code> methods
88  *  round their return values.  This should be set to one of the following
89  *  constants:
90  *  <deflist>
91  *  <term><code>NSRoundDown</code></term>
92  *  <desc>Always round down.</desc>
93  *  <term><code>NSRoundUp</code></term>
94  *  <desc>Always round up.</desc>
95  *  <term><code>NSRoundPlain</code></term>
96  *  <desc>Round to the closest possible return value.  Halfway (e.g. .5)
97  *  rounds up for positive numbers, down for negative (towards larger absolute
98  *  value).</desc>
99  *  <term><code>NSRoundBankers</code></term>
100  *  <desc>Round to the closest possible return value, but halfway (e.g. .5)
101  *  rounds towards  possibility whose last digit is even.</desc>
102  * </deflist>
103  */
104 - (NSRoundingMode) roundingMode;
105 
106 /**
107  *  Specifies the precision of the values returned by [NSDecimalNumber]'s
108  *  <code>decimalNumberBy...</code> methods, in terms of the number of
109  *  digits allowed after the decimal point.  This can be negative, implying
110  *  that the precision should be, e.g., 100's, 1000's, etc..  For unlimited
111  *  precision, set to <code>NSDecimalNoScale</code>.
112  */
113 - (short) scale;
114 @end
115 
116 /**
117  *  A utility class adopting [(NSDecimalNumberBehaviors)] protocol.  Can be used
118  *  to control [NSDecimalNumber] rounding and exception-handling behavior, by
119  *  passing an instance as an argument to any [NSDecimalNumber] method ending
120  *  with <code>...Behavior:</code>.
121  */
122 @interface	NSDecimalNumberHandler : NSObject <NSDecimalNumberBehaviors>
123 {
124 #if	GS_EXPOSE(NSDecimalNumberHandler)
125   NSRoundingMode _roundingMode;
126   short _scale;
127   BOOL _raiseOnExactness;
128   BOOL _raiseOnOverflow;
129   BOOL _raiseOnUnderflow;
130   BOOL _raiseOnDivideByZero;
131 #endif
132 #if     GS_NONFRAGILE
133 #else
134   /* Pointer to private additional data used to avoid breaking ABI
135    * when we don't have the non-fragile ABI available.
136    * Use this mechanism rather than changing the instance variable
137    * layout (see Source/GSInternal.h for details).
138    */
139   @private id _internal GS_UNUSED_IVAR;
140 #endif
141 }
142 
143 /**
144  *  Provides an instance implementing the default behavior for the
145  *  [NSDecimalNumber] class.  38 decimal digits, rounded to closest return
146  *  value (<code>NSRoundPlain</code>).  Exceptions raised on overflow,
147  *  underflow, and divide by zero.
148  */
149 + (id)defaultDecimalNumberHandler;
150 
151 /**
152  * Constructor setting all behavior.  (For more precise control over error
153  * handling, create your own class implementing the [(NSDecimalNumberBehaviors)]
154  * protocol.)
155  */
156 + (id)decimalNumberHandlerWithRoundingMode:(NSRoundingMode)roundingMode
157 				     scale:(short)scale
158 			  raiseOnExactness:(BOOL)raiseOnExactness
159 			   raiseOnOverflow:(BOOL)raiseOnOverflow
160 			  raiseOnUnderflow:(BOOL)raiseOnUnderflow
161 		       raiseOnDivideByZero:(BOOL)raiseOnDivideByZero;
162 
163 /**
164  * Initializer setting all behavior.  (For more precise control over error
165  * handling, create your own class implementing the [(NSDecimalNumberBehaviors)]
166  * protocol.)
167  */
168 - (id)initWithRoundingMode:(NSRoundingMode)roundingMode
169 		     scale:(short)scale
170 	  raiseOnExactness:(BOOL)raiseOnExactness
171 	   raiseOnOverflow:(BOOL)raiseOnOverflow
172 	  raiseOnUnderflow:(BOOL)raiseOnUnderflow
173        raiseOnDivideByZero:(BOOL)raiseOnDivideByZero;
174 @end
175 
176 /**
177  *  <p>Class that implements a number of methods for performing decimal
178  *  arithmetic to arbitrary precision. The behavior in terms of rounding
179  *  choices and exception handling may be customized using the
180  *  [NSDecimalNumberHandler] class, and defaults to
181  *  [NSDecimalNumberHandler+defaultDecimalNumberHandler].</p>
182  *
183  *  <p>Equivalent functionality to the <code>NSDecimalNumber</code> class may
184  *  be accessed through functions, mostly named <code>NSDecimalXXX</code>,
185  *  e.g., NSDecimalMin().  Both the class and the functions use a structure
186  *  called <code>NSDecimal</code>.</p>
187  *
188  *  <p>Note that instances of <code>NSDecimalNumber</code> are immutable.</p>
189  */
190 @interface	NSDecimalNumber : NSNumber <NSDecimalNumberBehaviors>
191 {
192 #if	GS_EXPOSE(NSDecimalNumber)
193   NSDecimal data;
194 #endif
195 }
196 
197 /**
198  *  Returns the default rounding/precision/exception handling behavior, which
199  *  is same as [NSDecimalNumberHandler+defaultDecimalNumberHandler] unless it
200  *  has been explicitly set otherwise.
201  */
202 + (id <NSDecimalNumberBehaviors>)defaultBehavior;
203 
204 /**
205  *  Sets the default rounding/precision/exception handling behavior to the
206  *  given behavior.  If this is not called, behavior defaults to
207  *  [NSDecimalNumberHandler+defaultDecimalNumberHandler].
208  */
209 + (void)setDefaultBehavior:(id <NSDecimalNumberBehaviors>)behavior;
210 
211 /**
212  *  Return maximum positive value that can be represented.
213  */
214 + (NSDecimalNumber *)maximumDecimalNumber;
215 
216 /**
217  *  Return minimum negative value (<em>not</em> the smallest positive value)
218  *  that can be represented.
219  */
220 + (NSDecimalNumber *)minimumDecimalNumber;
221 
222 /**
223  *  Return a fixed value representing an NaN.
224  */
225 + (NSDecimalNumber *)notANumber;
226 
227 /**
228  *  Return a constant object with a value of one.
229  */
230 + (NSDecimalNumber *)one;
231 
232 /**
233  *  Return a constant object with a value of zero.
234  */
235 + (NSDecimalNumber *)zero;
236 
237 /**
238  *  New instance with given value.  Note an NSDecimal may be created using the
239  *  function NSDecimalFromString().
240  */
241 + (NSDecimalNumber *)decimalNumberWithDecimal:(NSDecimal)decimal;
242 
243 /**
244  *  New instance by component.  Note that the precision of this initializer is
245  *  limited.
246  */
247 + (NSDecimalNumber *)decimalNumberWithMantissa:(unsigned long long)mantissa
248 				      exponent:(short)exponent
249 				    isNegative:(BOOL)isNegative;
250 
251 /**
252  *  New instance from string.  Arbitrary precision is preserved, though calling
253  *  one of the <code>decimalNumberBy...</code> methods will return a result
254  *  constrained by the current <em><code>scale</code></em>.  Number format
255  *  is parsed according to current default locale.
256  */
257 + (NSDecimalNumber *)decimalNumberWithString:(NSString *)numericString;
258 
259 /**
260  *  New instance from string.  Arbitrary precision is preserved, though calling
261  *  one of the <code>decimalNumberBy...</code> methods will return a result
262  *  constrained by the current <em><code>scale</code></em>.  Number format
263  *  is parsed according to given locale.
264  */
265 + (NSDecimalNumber *)decimalNumberWithString:(NSString *)numericString
266 				      locale:(NSDictionary *)locale;
267 
268 /**
269  *  Initialize with given value.  Note an NSDecimal may be created using the
270  *  function NSDecimalFromString().
271  */
272 - (id)initWithDecimal:(NSDecimal)decimal;
273 
274 /**
275  *  Initialize by component.  Note that the precision of this initializer is
276  *  limited.
277  */
278 - (id)initWithMantissa:(unsigned long long)mantissa
279 	      exponent:(short)exponent
280 	    isNegative:(BOOL)flag;
281 
282 /**
283  *  Initialize from string.  Arbitrary precision is preserved, though calling
284  *  one of the <code>decimalNumberBy...</code> methods will return a result
285  *  constrained by the current <em><code>scale</code></em>.  Number format
286  *  is parsed according to current default locale.
287  */
288 - (id)initWithString:(NSString *)numberValue;
289 
290 /**
291  *  Initialize from string.  Arbitrary precision is preserved, though calling
292  *  one of the <code>decimalNumberBy...</code> methods will return a result
293  *  constrained by the current <em><code>scale</code></em>.  Number format
294  *  is parsed according to given locale.
295  */
296 - (id)initWithString:(NSString *)numberValue
297 	      locale:(NSDictionary *)locale;
298 
299 /**
300  *  Returns the Objective-C type (<code>@encode(...)</code> compatible) of the
301  *  data contained <code>NSDecimalNumber</code>, which is by convention "d"
302  *  (for double), even though this is not strictly accurate.
303  */
304 - (const char *)objCType;
305 
306 /**
307  *  Return underlying value as an <code>NSDecimal</code> structure.
308  */
309 - (NSDecimal)decimalValue;
310 
311 /**
312  *  Returns string version of number formatted according to locale.
313  */
314 - (NSString *)descriptionWithLocale:(id)locale;
315 
316 /**
317  *  Returns underlying value as a <code>double</code>, which may be an
318  *  approximation if precision greater than the default of 38.
319  */
320 - (double)doubleValue;
321 
322 
323 /**
324  *  Compares with other number, returning less, greater, or equal.
325  */
326 - (NSComparisonResult)compare:(NSNumber *)decimalNumber;
327 
328 /**
329  *  Adds self to decimalNumber and returns new result, using +defaultBehavior
330  *  for rounding/precision/error handling.
331  */
332 - (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber;
333 
334 /**
335  *  Adds self to decimalNumber and returns new result, using given behavior
336  *  for rounding/precision/error handling.
337  */
338 - (NSDecimalNumber *)decimalNumberByAdding:(NSDecimalNumber *)decimalNumber
339 			      withBehavior:(id<NSDecimalNumberBehaviors>)behavior;
340 
341 /**
342  *  Divides self by decimalNumber and returns new result, using +defaultBehavior
343  *  for rounding/precision/error handling.
344  */
345 - (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber;
346 
347 /**
348  *  Divides self by decimalNumber and returns new result, using given behavior
349  *  for rounding/precision/error handling.
350  */
351 - (NSDecimalNumber *)decimalNumberByDividingBy:(NSDecimalNumber *)decimalNumber
352 				  withBehavior:(id <NSDecimalNumberBehaviors>)behavior;
353 
354 /**
355  *  Multiplies self by decimalNumber and returns new result, using
356  *  +defaultBehavior for rounding/precision/error handling.
357  */
358 - (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber;
359 
360 /**
361  *  Multiplies self by decimalNumber and returns new result, using given
362  *  behavior for rounding/precision/error handling.
363  */
364 - (NSDecimalNumber *)decimalNumberByMultiplyingBy:(NSDecimalNumber *)decimalNumber
365 				     withBehavior:(id <NSDecimalNumberBehaviors>)behavior;
366 
367 /**
368  *  Multiplies self by given power of 10 and returns new result, using
369  *  +defaultBehavior for rounding/precision/error handling.
370  */
371 - (NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power;
372 
373 /**
374  *  Multiplies self by given power of 10 and returns new result, using given
375  *  behavior for rounding/precision/error handling.
376  */
377 - (NSDecimalNumber *)decimalNumberByMultiplyingByPowerOf10:(short)power
378   withBehavior:(id <NSDecimalNumberBehaviors>)behavior;
379 
380 /**
381  *  Raises self to given positive integer power and returns new result, using
382  *  +defaultBehavior for rounding/precision/error handling.
383  */
384 - (NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power;
385 
386 /**
387  *  Raises self to given positive integer power and returns new result, using
388  *  given behavior for rounding/precision/error handling.
389  */
390 - (NSDecimalNumber *)decimalNumberByRaisingToPower:(NSUInteger)power
391   withBehavior:(id <NSDecimalNumberBehaviors>)behavior;
392 
393 /**
394  *  Subtracts decimalNumber from self and returns new result, using
395  *  +defaultBehavior for rounding/precision/error handling.
396  */
397 - (NSDecimalNumber *)decimalNumberBySubtracting:
398   (NSDecimalNumber *)decimalNumber;
399 
400 /**
401  *  Subtracts decimalNumber from self and returns new result, using given
402  *  behavior for rounding/precision/error handling.
403  */
404 - (NSDecimalNumber *)decimalNumberBySubtracting:
405   (NSDecimalNumber *)decimalNumber
406   withBehavior:(id <NSDecimalNumberBehaviors>)behavior;
407 
408 /**
409  *  Returns rounded version of underlying decimal.
410  */
411 - (NSDecimalNumber *)decimalNumberByRoundingAccordingToBehavior:(id <NSDecimalNumberBehaviors>)behavior;
412 
413 @end
414 
415 /**
416  *  Interface for obtaining an NSDecimalNumber value from an ordinary
417  *  NSNumber.
418  */
419 @interface NSNumber (NSDecimalNumber)
420 /**
421  *  Obtaining an NSDecimalNumber version of an ordinary NSNumber.
422  */
423 - (NSDecimal) decimalValue;
424 @end
425 
426 #if	defined(__cplusplus)
427 }
428 #endif
429 
430 #endif
431 #endif
432