/* NSDecimal types and functions Copyright (C) 1998 Free Software Foundation, Inc. Written by: Richard Frith-Macdonald Created: November 1998 This file is part of the GNUstep Base Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 31 Milk Street #960789 Boston, MA 02196 USA. */ #ifndef __NSDecimal_h_GNUSTEP_BASE_INCLUDE #define __NSDecimal_h_GNUSTEP_BASE_INCLUDE #import #import #import #if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) #if USE_GMP #include #endif #if defined(__cplusplus) extern "C" { #endif /** * Enumerated type for specifying decimal rounding behavior. Can be one of * NSRoundDown (always round down), NSRoundUp * (always round up), NSRoundPlain ("normal" rounding (up from * .5 or above, down otherwise), NSRoundBankers (as "Plain" but * .5 rounds to make last remaining digit even). See the * [(NSDecimalNumberBehaviors)] protocol. */ enum { NSRoundPlain, /* Round .5 up */ NSRoundDown, NSRoundUp, NSRoundBankers /* Make last digit even */ }; typedef NSUInteger NSRoundingMode; /** * Enumerated type for specifying a decimal calculation error. Can be one of * the following: * * NSCalculationNoError * No error occurred. * NSCalculationLossOfPrecision * The number can't be represented in 38 significant digits. * NSCalculationOverflow * The number is too large to represent. * NSCalculationUnderflow * The number is too small to represent. * NSCalculationDivideByZero * The caller tried to divide by 0. * */ enum { NSCalculationNoError = 0, NSCalculationLossOfPrecision, NSCalculationUnderflow, /* result became zero */ NSCalculationOverflow, NSCalculationDivideByZero }; typedef NSUInteger NSCalculationError; /** * Give a precision of at least 38 decimal digits * requires 128 bits. */ #define NSDecimalMaxSize (16/sizeof(mp_limb_t)) #define NSDecimalMaxDigit 38 #define NSDecimalNoScale 128 /** *

Structure providing equivalent functionality, in conjunction with a set * of functions, to the [NSDecimalNumber] class.

typedef struct { signed char exponent; // Signed exponent - -128 to 127 BOOL isNegative; // Is this negative? BOOL validNumber; // Is this a valid number? unsigned char length; // digits in mantissa. unsigned char cMantissa[2*NSDecimalMaxDigit]; } NSDecimal; *

Instances can be initialized using the NSDecimalFromString(NSString *) * function.

*/ typedef struct { signed char exponent; /* Signed exponent - -128 to 127 */ BOOL isNegative; /* Is this negative? */ BOOL validNumber; /* Is this a valid number? */ #if USE_GMP mp_size_t size; mp_limb_t lMantissa[NSDecimalMaxSize]; #else unsigned char length; /* digits in mantissa. */ unsigned char cMantissa[NSDecimalMaxDigit]; #endif } NSDecimal; /** Returns whether decimal represents an invalid number (i.e., an "NaN" as might result from an overflow or a division by zero). */ static inline BOOL NSDecimalIsNotANumber(const NSDecimal *decimal) { return (decimal->validNumber == NO); } /** Copies value of decimal number to preallocated destination. */ GS_EXPORT void NSDecimalCopy(NSDecimal *destination, const NSDecimal *source); /** Tries to reduce memory used to store number internally. */ GS_EXPORT void NSDecimalCompact(NSDecimal *number); /** * Returns NSOrderedDescending, NSOrderedSame, or * NSOrderedAscending depending on whether leftOperand is * greater than, equal to, or less than rightOperand. */ GS_EXPORT NSComparisonResult NSDecimalCompare(const NSDecimal *leftOperand, const NSDecimal *rightOperand); /** * Rounds number to result such that it has at most scale digits to the right * of its decimal point, according to mode (see the * [(NSDecimalNumberBehaviors)] protocol). The result should be preallocated * but can be the same as number. */ GS_EXPORT void NSDecimalRound(NSDecimal *result, const NSDecimal *number, NSInteger scale, NSRoundingMode mode); /** * Sets the exponents of n1 and n2 equal to one another, adjusting mantissas * as necessary to preserve values. This makes certain operations quicker. */ GS_EXPORT NSCalculationError NSDecimalNormalize(NSDecimal *n1, NSDecimal *n2, NSRoundingMode mode); /** * Adds two decimals and returns result to 38-digit precision. See the * [(NSDecimalNumberBehaviors)] protocol for a description of mode and the * return value. The result should be preallocated but can be the same as * left or right. */ GS_EXPORT NSCalculationError NSDecimalAdd(NSDecimal *result, const NSDecimal *left, const NSDecimal *right, NSRoundingMode mode); /** * Subtracts two decimals and returns result to 38-digit precision. See the * [(NSDecimalNumberBehaviors)] protocol for a description of mode and the * return value. The result should be preallocated but can be the same as * left or right. */ GS_EXPORT NSCalculationError NSDecimalSubtract(NSDecimal *result, const NSDecimal *left, const NSDecimal *right, NSRoundingMode mode); /** * Multiplies two decimals and returns result to 38-digit precision. See the * [(NSDecimalNumberBehaviors)] protocol for a description of mode and the * return value. The result should be preallocated but can be the same as * l or r. */ GS_EXPORT NSCalculationError NSDecimalMultiply(NSDecimal *result, const NSDecimal *l, const NSDecimal *r, NSRoundingMode mode); /** * Divides l by rr and returns result to 38-digit precision. See the * [(NSDecimalNumberBehaviors)] protocol for a description of mode and the * return value. The result should be preallocated but can be the same as * l or rr. */ GS_EXPORT NSCalculationError NSDecimalDivide(NSDecimal *result, const NSDecimal *l, const NSDecimal *rr, NSRoundingMode mode); /** * Raises n to power and returns result to 38-digit precision. See the * [(NSDecimalNumberBehaviors)] protocol for a description of mode and the * return value. The result should be preallocated but can be the same as * n or power. */ GS_EXPORT NSCalculationError NSDecimalPower(NSDecimal *result, const NSDecimal *n, NSUInteger power, NSRoundingMode mode); /** * Multiplies n by 10^power and returns result to 38-digit precision. See the * [(NSDecimalNumberBehaviors)] protocol for a description of mode and the * return value. The result should be preallocated but can be the same as * n. */ GS_EXPORT NSCalculationError NSDecimalMultiplyByPowerOf10(NSDecimal *result, const NSDecimal *n, short power, NSRoundingMode mode); /** * Returns a string representing the full decimal value, formatted according * to locale (send nil here for default locale). */ GS_EXPORT NSString* NSDecimalString(const NSDecimal *decimal, NSDictionary *locale); // GNUstep extensions to make the implementation of NSDecimalNumber totaly // independent for NSDecimals internal representation /** Give back the biggest NSDecimal in (preallocated) result. */ GS_EXPORT void NSDecimalMax(NSDecimal *result); /** Give back the smallest NSDecimal in (preallocated) result. */ GS_EXPORT void NSDecimalMin(NSDecimal *result); /** Give back the value of a NSDecimal as a double in (preallocated) result. */ GS_EXPORT double NSDecimalDouble(NSDecimal *number); /** * Create a NSDecimal with a mantissa, exponent and a negative flag in * (preallocated) result. */ GS_EXPORT void NSDecimalFromComponents(NSDecimal *result, unsigned long long mantissa, short exponent, BOOL negative); /** * Create a NSDecimal from a string using the locale, in (preallocated) * result. */ GS_EXPORT void NSDecimalFromString(NSDecimal *result, NSString *numberValue, NSDictionary *locale); #if defined(__cplusplus) } #endif #endif #endif