This is extract from #211 that enables compilation with GCC. With #211 now in the state of bitrot, I would rather try approaching it in smaller steps that can be hopefully merged quicker, even if it does not provide full support for all the features #211 provided. This will _compile_ correctly with my (@janisozaur) GCC, but clang is more picky about flexible array members and refuses to compile it yet. I will extract remaining parts of #211 in future PRs. I marked @fwcd as author, as he did most of the work in #211.
491 lines
30 KiB
C++
491 lines
30 KiB
C++
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License.
|
|
|
|
#pragma once
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Package Title ratpak
|
|
// File ratpak.h
|
|
// Copyright (C) 1995-99 Microsoft
|
|
// Date 01-16-95
|
|
//
|
|
//
|
|
// Description
|
|
//
|
|
// Infinite precision math package header file, if you use ratpak.lib you
|
|
// need to include this header.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#include <algorithm>
|
|
#include <string>
|
|
#include "CalcErr.h"
|
|
#include <cstring> // for memmove
|
|
#include "sal_cross_platform.h" // for SAL
|
|
|
|
static constexpr uint32_t BASEXPWR = 31L; // Internal log2(BASEX)
|
|
static constexpr uint32_t BASEX = 0x80000000; // Internal radix used in calculations, hope to raise
|
|
// this to 2^32 after solving scaling problems with
|
|
// overflow detection esp. in mul
|
|
|
|
typedef uint32_t MANTTYPE;
|
|
typedef uint64_t TWO_MANTTYPE;
|
|
|
|
enum eNUMOBJ_FMT
|
|
{
|
|
FMT_FLOAT, // returns floating point, or exponential if number is too big
|
|
FMT_SCIENTIFIC, // always returns scientific notation
|
|
FMT_ENGINEERING // always returns engineering notation such that exponent is a multiple of 3
|
|
|
|
};
|
|
|
|
enum eANGLE_TYPE
|
|
{
|
|
ANGLE_DEG, // Calculate trig using 360 degrees per revolution
|
|
ANGLE_RAD, // Calculate trig using 2 pi radians per revolution
|
|
ANGLE_GRAD // Calculate trig using 400 gradients per revolution
|
|
|
|
};
|
|
|
|
typedef enum eNUMOBJ_FMT NUMOBJ_FMT;
|
|
typedef enum eANGLE_TYPE ANGLE_TYPE;
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// NUMBER type is a representation of a generic sized generic radix number
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#pragma warning(push)
|
|
#pragma warning(disable : 4200) // nonstandard extension used : zero-sized array in struct/union
|
|
typedef struct _number
|
|
{
|
|
int32_t sign; // The sign of the mantissa, +1, or -1
|
|
int32_t cdigit; // The number of digits, or what passes for digits in the
|
|
// radix being used.
|
|
int32_t exp; // The offset of digits from the radix point
|
|
// (decimal point in radix 10)
|
|
MANTTYPE mant[];
|
|
// This is actually allocated as a continuation of the
|
|
// NUMBER structure.
|
|
} NUMBER, *PNUMBER, **PPNUMBER;
|
|
#pragma warning(pop)
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// RAT type is a representation radix on 2 NUMBER types.
|
|
// pp/pq, where pp and pq are pointers to integral NUMBER types.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
typedef struct _rat
|
|
{
|
|
PNUMBER pp;
|
|
PNUMBER pq;
|
|
} RAT, *PRAT;
|
|
|
|
static constexpr uint32_t MAX_LONG_SIZE = 33; // Base 2 requires 32 'digits'
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// List of useful constants for evaluation, note this list needs to be
|
|
// initialized.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
extern PNUMBER num_one;
|
|
extern PNUMBER num_two;
|
|
extern PNUMBER num_five;
|
|
extern PNUMBER num_six;
|
|
extern PNUMBER num_ten;
|
|
|
|
extern PRAT ln_ten;
|
|
extern PRAT ln_two;
|
|
extern PRAT rat_zero;
|
|
extern PRAT rat_neg_one;
|
|
extern PRAT rat_one;
|
|
extern PRAT rat_two;
|
|
extern PRAT rat_six;
|
|
extern PRAT rat_half;
|
|
extern PRAT rat_ten;
|
|
extern PRAT pt_eight_five;
|
|
extern PRAT pi;
|
|
extern PRAT pi_over_two;
|
|
extern PRAT two_pi;
|
|
extern PRAT one_pt_five_pi;
|
|
extern PRAT e_to_one_half;
|
|
extern PRAT rat_exp;
|
|
extern PRAT rad_to_deg;
|
|
extern PRAT rad_to_grad;
|
|
extern PRAT rat_qword;
|
|
extern PRAT rat_dword;
|
|
extern PRAT rat_word;
|
|
extern PRAT rat_byte;
|
|
extern PRAT rat_360;
|
|
extern PRAT rat_400;
|
|
extern PRAT rat_180;
|
|
extern PRAT rat_200;
|
|
extern PRAT rat_nRadix;
|
|
extern PRAT rat_smallest;
|
|
extern PRAT rat_negsmallest;
|
|
extern PRAT rat_max_exp;
|
|
extern PRAT rat_min_exp;
|
|
extern PRAT rat_max_fact;
|
|
extern PRAT rat_min_fact;
|
|
extern PRAT rat_max_i32;
|
|
extern PRAT rat_min_i32;
|
|
|
|
// DUPNUM Duplicates a number taking care of allocation and internals
|
|
#define DUPNUM(a, b) \
|
|
destroynum(a); \
|
|
createnum(a, (b)->cdigit); \
|
|
_dupnum(a, b);
|
|
|
|
// DUPRAT Duplicates a rational taking care of allocation and internals
|
|
#define DUPRAT(a, b) \
|
|
destroyrat(a); \
|
|
createrat(a); \
|
|
DUPNUM((a)->pp, (b)->pp); \
|
|
DUPNUM((a)->pq, (b)->pq);
|
|
|
|
// LOG*RADIX calculates the integral portion of the log of a number in
|
|
// the base currently being used, only accurate to within g_ratio
|
|
|
|
#define LOGNUMRADIX(pnum) (((pnum)->cdigit + (pnum)->exp) * g_ratio)
|
|
#define LOGRATRADIX(prat) (LOGNUMRADIX((prat)->pp) - LOGNUMRADIX((prat)->pq))
|
|
|
|
// LOG*2 calculates the integral portion of the log of a number in
|
|
// the internal base being used, only accurate to within g_ratio
|
|
|
|
#define LOGNUM2(pnum) ((pnum)->cdigit + (pnum)->exp)
|
|
#define LOGRAT2(prat) (LOGNUM2((prat)->pp) - LOGNUM2((prat)->pq))
|
|
|
|
// SIGN returns the sign of the rational
|
|
#define SIGN(prat) ((prat)->pp->sign * (prat)->pq->sign)
|
|
|
|
#if defined(DEBUG_RATPAK)
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Debug versions of rational number creation and destruction routines.
|
|
// used for debugging allocation errors.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define createrat(y) \
|
|
(y) = _createrat(); \
|
|
{ \
|
|
std::wstringstream outputString; \
|
|
outputString << "createrat " << y << " " << #y << " file= " << __FILE__ << ", line= " << __LINE__ << "\n"; \
|
|
OutputDebugString(outputString.str().c_str()); \
|
|
}
|
|
#define destroyrat(x) \
|
|
{ \
|
|
std::wstringstream outputString; \
|
|
outputString << "destroyrat " << x << " file= " << __FILE__ << ", line= " << __LINE__ << "\n"; \
|
|
OutputDebugString(outputString.str().c_str()); \
|
|
} \
|
|
_destroyrat(x), (x) = nullptr
|
|
#define createnum(y, x) \
|
|
(y) = _createnum(x); \
|
|
{ \
|
|
std::wstringstream outputString; \
|
|
outputString << "createnum " << y << " " << #y << " file= " << __FILE__ << ", line= " << __LINE__ << "\n"; \
|
|
OutputDebugString(outputString.str().c_str()); \
|
|
}
|
|
#define destroynum(x) \
|
|
{ \
|
|
std::wstringstream outputString; \
|
|
outputString << "destroynum " << x << " file= " << __FILE__ << ", line= " << __LINE__ << "\n"; \
|
|
OutputDebugString(outputString.str().c_str()); \
|
|
} \
|
|
_destroynum(x), (x) = nullptr
|
|
#else
|
|
#define createrat(y) (y) = _createrat()
|
|
#define destroyrat(x) _destroyrat(x), (x) = nullptr
|
|
#define createnum(y, x) (y) = _createnum(x)
|
|
#define destroynum(x) _destroynum(x), (x) = nullptr
|
|
#endif
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Defines for checking when to stop taylor series expansions due to
|
|
// precision satisfaction.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// RENORMALIZE, gets the exponents non-negative.
|
|
#define RENORMALIZE(x) \
|
|
if ((x)->pp->exp < 0) \
|
|
{ \
|
|
(x)->pq->exp -= (x)->pp->exp; \
|
|
(x)->pp->exp = 0; \
|
|
} \
|
|
if ((x)->pq->exp < 0) \
|
|
{ \
|
|
(x)->pp->exp -= (x)->pq->exp; \
|
|
(x)->pq->exp = 0; \
|
|
}
|
|
|
|
// TRIMNUM ASSUMES the number is in radix form NOT INTERNAL BASEX!!!
|
|
#define TRIMNUM(x, precision) \
|
|
if (!g_ftrueinfinite) \
|
|
{ \
|
|
int32_t trim = (x)->cdigit - precision - g_ratio; \
|
|
if (trim > 1) \
|
|
{ \
|
|
memmove((x)->mant, &((x)->mant[trim]), sizeof(MANTTYPE) * ((x)->cdigit - trim)); \
|
|
(x)->cdigit -= trim; \
|
|
(x)->exp += trim; \
|
|
} \
|
|
}
|
|
// TRIMTOP ASSUMES the number is in INTERNAL BASEX!!!
|
|
#define TRIMTOP(x, precision) \
|
|
if (!g_ftrueinfinite) \
|
|
{ \
|
|
int32_t trim = (x)->pp->cdigit - (precision / g_ratio) - 2; \
|
|
if (trim > 1) \
|
|
{ \
|
|
memmove((x)->pp->mant, &((x)->pp->mant[trim]), sizeof(MANTTYPE) * ((x)->pp->cdigit - trim)); \
|
|
(x)->pp->cdigit -= trim; \
|
|
(x)->pp->exp += trim; \
|
|
} \
|
|
trim = std::min((x)->pp->exp, (x)->pq->exp); \
|
|
(x)->pp->exp -= trim; \
|
|
(x)->pq->exp -= trim; \
|
|
}
|
|
|
|
#define SMALL_ENOUGH_RAT(a, precision) (zernum((a)->pp) || ((((a)->pq->cdigit + (a)->pq->exp) - ((a)->pp->cdigit + (a)->pp->exp) - 1) * g_ratio > precision))
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Defines for setting up taylor series expansions for infinite precision
|
|
// functions.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
#define CREATETAYLOR() \
|
|
PRAT xx = nullptr; \
|
|
PNUMBER n2 = nullptr; \
|
|
PRAT pret = nullptr; \
|
|
PRAT thisterm = nullptr; \
|
|
DUPRAT(xx, *px); \
|
|
mulrat(&xx, *px, precision); \
|
|
createrat(pret); \
|
|
pret->pp = i32tonum(0L, BASEX); \
|
|
pret->pq = i32tonum(0L, BASEX);
|
|
|
|
#define DESTROYTAYLOR() \
|
|
destroynum(n2); \
|
|
destroyrat(xx); \
|
|
destroyrat(thisterm); \
|
|
destroyrat(*px); \
|
|
trimit(&pret, precision); \
|
|
*px = pret;
|
|
|
|
// INC(a) is the rational equivalent of a++
|
|
// Check to see if we can avoid doing this the hard way.
|
|
#define INC(a) \
|
|
if ((a)->mant[0] < BASEX - 1) \
|
|
{ \
|
|
(a)->mant[0]++; \
|
|
} \
|
|
else \
|
|
{ \
|
|
addnum(&(a), num_one, BASEX); \
|
|
}
|
|
|
|
#define MSD(x) ((x)->mant[(x)->cdigit - 1])
|
|
// MULNUM(b) is the rational equivalent of thisterm *= b where thisterm is
|
|
// a rational and b is a number, NOTE this is a mixed type operation for
|
|
// efficiency reasons.
|
|
#define MULNUM(b) mulnumx(&(thisterm->pp), b);
|
|
|
|
// DIVNUM(b) is the rational equivalent of thisterm /= b where thisterm is
|
|
// a rational and b is a number, NOTE this is a mixed type operation for
|
|
// efficiency reasons.
|
|
#define DIVNUM(b) mulnumx(&(thisterm->pq), b);
|
|
|
|
// NEXTTERM(p,d) is the rational equivalent of
|
|
// thisterm *= p
|
|
// d <d is usually an expansion of operations to get thisterm updated.>
|
|
// pret += thisterm
|
|
#define NEXTTERM(p, d, precision) \
|
|
mulrat(&thisterm, p, precision); \
|
|
d addrat(&pret, thisterm, precision)
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// External variables used in the math package.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
extern bool g_ftrueinfinite; // set to true to allow infinite precision
|
|
// don't use unless you know what you are doing
|
|
// used to help decide when to stop calculating.
|
|
|
|
extern int32_t g_ratio; // Internally calculated ratio of internal radix
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// External functions defined in the math package.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Call whenever decimal separator character changes.
|
|
extern void SetDecimalSeparator(wchar_t decimalSeparator);
|
|
|
|
// Call whenever either radix or precision changes, is smarter about recalculating constants.
|
|
extern void ChangeConstants(uint32_t radix, int32_t precision);
|
|
|
|
extern bool equnum(_In_ PNUMBER a, _In_ PNUMBER b); // returns true of a == b
|
|
extern bool lessnum(_In_ PNUMBER a, _In_ PNUMBER b); // returns true of a < b
|
|
extern bool zernum(_In_ PNUMBER a); // returns true of a == 0
|
|
extern bool zerrat(_In_ PRAT a); // returns true if a == 0/q
|
|
extern std::wstring NumberToString(_Inout_ PNUMBER& pnum, int format, uint32_t radix, int32_t precision);
|
|
|
|
// returns a text representation of a PRAT
|
|
extern std::wstring RatToString(_Inout_ PRAT& prat, int format, uint32_t radix, int32_t precision);
|
|
// converts a PRAT into a PNUMBER
|
|
extern PNUMBER RatToNumber(_In_ PRAT prat, uint32_t radix, int32_t precision);
|
|
// flattens a PRAT by converting it to a PNUMBER and back to a PRAT
|
|
extern void flatrat(_Inout_ PRAT& prat, uint32_t radix, int32_t precision);
|
|
|
|
extern int32_t numtoi32(_In_ PNUMBER pnum, uint32_t radix);
|
|
extern int32_t rattoi32(_In_ PRAT prat, uint32_t radix, int32_t precision);
|
|
uint64_t rattoUi64(_In_ PRAT prat, uint32_t radix, int32_t precision);
|
|
extern PNUMBER _createnum(_In_ uint32_t size); // returns an empty number structure with size digits
|
|
extern PNUMBER nRadixxtonum(_In_ PNUMBER a, uint32_t radix, int32_t precision);
|
|
extern PNUMBER gcd(_In_ PNUMBER a, _In_ PNUMBER b);
|
|
extern PNUMBER StringToNumber(
|
|
std::wstring_view numberString,
|
|
uint32_t radix,
|
|
int32_t precision); // takes a text representation of a number and returns a number.
|
|
|
|
// takes a text representation of a number as a mantissa with sign and an exponent with sign.
|
|
extern PRAT
|
|
StringToRat(bool mantissaIsNegative, std::wstring_view mantissa, bool exponentIsNegative, std::wstring_view exponent, uint32_t radix, int32_t precision);
|
|
|
|
extern PNUMBER i32factnum(int32_t ini32, uint32_t radix);
|
|
extern PNUMBER i32prodnum(int32_t start, int32_t stop, uint32_t radix);
|
|
extern PNUMBER i32tonum(int32_t ini32, uint32_t radix);
|
|
extern PNUMBER Ui32tonum(uint32_t ini32, uint32_t radix);
|
|
extern PNUMBER numtonRadixx(PNUMBER a, uint32_t radix);
|
|
|
|
// creates a empty/undefined rational representation (p/q)
|
|
extern PRAT _createrat(void);
|
|
|
|
// returns a new rat structure with the acos of x->p/x->q taking into account
|
|
// angle type
|
|
extern void acosanglerat(_Inout_ PRAT* px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the acosh of x->p/x->q
|
|
extern void acoshrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the acos of x->p/x->q
|
|
extern void acosrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the asin of x->p/x->q taking into account
|
|
// angle type
|
|
extern void asinanglerat(_Inout_ PRAT* px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
|
|
|
|
extern void asinhrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
// returns a new rat structure with the asinh of x->p/x->q
|
|
|
|
// returns a new rat structure with the asin of x->p/x->q
|
|
extern void asinrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the atan of x->p/x->q taking into account
|
|
// angle type
|
|
extern void atananglerat(_Inout_ PRAT* px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the atanh of x->p/x->q
|
|
extern void atanhrat(_Inout_ PRAT* px, int32_t precision);
|
|
|
|
// returns a new rat structure with the atan of x->p/x->q
|
|
extern void atanrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the cosh of x->p/x->q
|
|
extern void coshrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the cos of x->p/x->q
|
|
extern void cosrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the cos of x->p/x->q taking into account
|
|
// angle type
|
|
extern void cosanglerat(_Inout_ PRAT* px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the exp of x->p/x->q this should not be called explicitly.
|
|
extern void _exprat(_Inout_ PRAT* px, int32_t precision);
|
|
|
|
// returns a new rat structure with the exp of x->p/x->q
|
|
extern void exprat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the log base 10 of x->p/x->q
|
|
extern void log10rat(_Inout_ PRAT* px, int32_t precision);
|
|
|
|
// returns a new rat structure with the natural log of x->p/x->q
|
|
extern void lograt(_Inout_ PRAT* px, int32_t precision);
|
|
|
|
extern PRAT i32torat(int32_t ini32);
|
|
extern PRAT Ui32torat(uint32_t inui32);
|
|
extern PRAT numtorat(_In_ PNUMBER pin, uint32_t radix);
|
|
|
|
extern void sinhrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
extern void sinrat(_Inout_ PRAT* px);
|
|
|
|
// returns a new rat structure with the sin of x->p/x->q taking into account
|
|
// angle type
|
|
extern void sinanglerat(_Inout_ PRAT* px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
|
|
|
|
extern void tanhrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
extern void tanrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
|
|
// returns a new rat structure with the tan of x->p/x->q taking into account
|
|
// angle type
|
|
extern void tananglerat(_Inout_ PRAT* px, ANGLE_TYPE angletype, uint32_t radix, int32_t precision);
|
|
|
|
extern void _dupnum(_In_ PNUMBER dest, _In_ const NUMBER* const src);
|
|
|
|
extern void _destroynum(_In_ PNUMBER pnum);
|
|
extern void _destroyrat(_In_ PRAT prat);
|
|
extern void addnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix);
|
|
extern void addrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision);
|
|
extern void andrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);
|
|
extern void divnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix, int32_t precision);
|
|
extern void divnumx(_Inout_ PNUMBER* pa, _In_ PNUMBER b, int32_t precision);
|
|
extern void divrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision);
|
|
extern void fracrat(_Inout_ PRAT* pa, uint32_t radix, int32_t precision);
|
|
extern void factrat(_Inout_ PRAT* pa, uint32_t radix, int32_t precision);
|
|
extern void remrat(_Inout_ PRAT* pa, _In_ PRAT b);
|
|
extern void modrat(_Inout_ PRAT* pa, _In_ PRAT b);
|
|
extern void gcdrat(_Inout_ PRAT* pa, int32_t precision);
|
|
extern void intrat(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
extern void mulnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix);
|
|
extern void mulnumx(_Inout_ PNUMBER* pa, _In_ PNUMBER b);
|
|
extern void mulrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision);
|
|
extern void numpowi32(_Inout_ PNUMBER* proot, int32_t power, uint32_t radix, int32_t precision);
|
|
extern void numpowi32x(_Inout_ PNUMBER* proot, int32_t power);
|
|
extern void orrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);
|
|
extern void powrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);
|
|
extern void powratNumeratorDenominator(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);
|
|
extern void powratcomp(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);
|
|
extern void ratpowi32(_Inout_ PRAT* proot, int32_t power, int32_t precision);
|
|
extern void remnum(_Inout_ PNUMBER* pa, _In_ PNUMBER b, uint32_t radix);
|
|
extern void rootrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);
|
|
extern void scale2pi(_Inout_ PRAT* px, uint32_t radix, int32_t precision);
|
|
extern void scale(_Inout_ PRAT* px, _In_ PRAT scalefact, uint32_t radix, int32_t precision);
|
|
extern void subrat(_Inout_ PRAT* pa, _In_ PRAT b, int32_t precision);
|
|
extern void xorrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);
|
|
extern void lshrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);
|
|
extern void rshrat(_Inout_ PRAT* pa, _In_ PRAT b, uint32_t radix, int32_t precision);
|
|
extern bool rat_equ(_In_ PRAT a, _In_ PRAT b, int32_t precision);
|
|
extern bool rat_neq(_In_ PRAT a, _In_ PRAT b, int32_t precision);
|
|
extern bool rat_gt(_In_ PRAT a, _In_ PRAT b, int32_t precision);
|
|
extern bool rat_ge(_In_ PRAT a, _In_ PRAT b, int32_t precision);
|
|
extern bool rat_lt(_In_ PRAT a, _In_ PRAT b, int32_t precision);
|
|
extern bool rat_le(_In_ PRAT a, _In_ PRAT b, int32_t precision);
|
|
extern void inbetween(_In_ PRAT* px, _In_ PRAT range, int32_t precision);
|
|
extern void trimit(_Inout_ PRAT* px, int32_t precision);
|
|
extern void _dumprawrat(_In_ const wchar_t* varname, _In_ PRAT rat, std::wostream& out);
|
|
extern void _dumprawnum(_In_ const wchar_t* varname, _In_ PNUMBER num, std::wostream& out);
|