mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 17:10:48 +00:00
263 lines
8.6 KiB
Objective-C
263 lines
8.6 KiB
Objective-C
/* NSDecimal types and functions
|
|
Copyright (C) 1998 Free Software Foundation, Inc.
|
|
|
|
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
|
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 <GNUstepBase/GSVersionMacros.h>
|
|
|
|
#import <GNUstepBase/GSConfig.h>
|
|
|
|
#import <Foundation/NSObject.h>
|
|
|
|
#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST)
|
|
|
|
#if USE_GMP
|
|
#include <gmp.h>
|
|
#endif
|
|
|
|
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* Enumerated type for specifying decimal rounding behavior. Can be one of
|
|
* <code>NSRoundDown</code> (always round down), <code>NSRoundUp</code>
|
|
* (always round up), <code>NSRoundPlain</code> ("normal" rounding (up from
|
|
* .5 or above, down otherwise), <code>NSRoundBankers</code> (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:
|
|
* <deflist>
|
|
* <term><code>NSCalculationNoError</code></term>
|
|
* <desc>No error occurred.</desc>
|
|
* <term><code>NSCalculationLossOfPrecision</code></term>
|
|
* <desc>The number can't be represented in 38 significant digits.</desc>
|
|
* <term><code>NSCalculationOverflow</code></term>
|
|
* <desc>The number is too large to represent.</desc>
|
|
* <term><code>NSCalculationUnderflow</code></term>
|
|
* <desc>The number is too small to represent.</desc>
|
|
* <term><code>NSCalculationDivideByZero</code></term>
|
|
* <desc>The caller tried to divide by 0.</desc>
|
|
* </deflist>
|
|
*/
|
|
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
|
|
|
|
/**
|
|
* <p>Structure providing equivalent functionality, in conjunction with a set
|
|
* of functions, to the [NSDecimalNumber] class.</p>
|
|
<example>
|
|
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;
|
|
</example>
|
|
* <p>Instances can be initialized using the NSDecimalFromString(NSString *)
|
|
* function.</p>
|
|
*/
|
|
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 <code>NSOrderedDescending</code>, <code>NSOrderedSame</code>, or
|
|
* <code>NSOrderedAscending</code> 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
|
|
|