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