/*************************************************************** __MPU_REAL.H This file contains declarations of functions for REAL arithmetic operations. PART OF : MPU - library . USAGE : Internal only . NOTE : Include "libmpu.h" before this FILE . Copyright (C) 2000 - 2024 by Andrew V.Kosteltsev. All Rights Reserved. ***************************************************************/ #ifndef __MPU_REAL_H #define __MPU_REAL_H #ifdef __cplusplus extern "C" { #endif /*************************************************************** Internal exploded e-type data structure of a real number (a EMUSHORT is BITS_PER_EMUSHORT bits): EMUSHORT ei[NP]; IF MPU_WORD_ORDER_BIG_ENDIAN = 1 (m68k, PowerPC) ei[0] - high EMUSHORT partion, ei[NP-1] - low EMUSHORT partion. - that is --------------------------------------- pointer -> [high EMUSHORT partion] :0 part [ . . . ] :1 part . . . [low EMUSHORT partion] :NP-1 part ------------------------------------------------- ELSE IF MPU_WORD_ORDER_BIG_ENDIAN = 0 (i386, Alpha) ei[0] - low EMUSHORT partion. ei[NP-1] - high EMUSHORT partion, - that is --------------------------------------- part 0: [low EMUSHORT partion] <- pointer part 1: [ . . . ] . . . part NP-1: [high EMUSHORT partion] ------------------------------------------------- =============================================================== index: MPU_WORD_ORDER_BIG_ENDIAN = 0 [nS+nE+2]|[nS+nE+1]...[nS+2]| [nS+1]|[nS], . . . , [1]| [0]. MPU_WORD_ORDER_BIG_ENDIAN = 1 [0]|[1], . . . , [nE]| [nE+1]|[nE+2], ...,[nE+nS+1]|[nE+nS+2]. |--------|------. . .-------|-------|---------. . .-------|---------| | sign | Exponent | hgw | Significand | lgw | |--------|------. . .-------|-------|---------. . .-------|---------| size: 1 nE 1 nS 1 hgw - hight guard word (always zero after normalization); lgw - low guard word (0x8000... bit is rounding place); sign - знак числа ( '+' - 0x0000...; '-' - 0xffff... ); Exponent - смещенный порядок; Significand - мантисса; Общее количество слов - nE + nS + 3; Бит целой (1.) - явный. СТАРШИЙ БИТ ЭКСПОНЕНТЫ НЕ ИСПОЛЬЗУЕТСЯ. ***************************************************************/ /*************************************************************** NOTE: Количество порций вещественного числа во внутреннем формате не должно превышать максимального значения EMUSHORT (unsigned int), которому соответствует тип __mpu_uint32_t. NOTE: Это ограничение связано с ограничением количества бит мантиссы вещественного числа во внутреннем формате. SEE: ei_normalize() in this file. NOTE: В случае программных моделей ILP32, LP64, LLP64 мы всегда можем иметь 32-битный EMUSHORT, что позволяет в качестве возвращаемого значения функции ei_normalize() использовать переменные типа __mpu_int32_t или int. ***************************************************************/ /*************************************************************** External exploded e-type data structure of a real number (a EMUPART is BITS_PER_EMUPART bits): =============================================================== index: MPU_WORD_ORDER_BIG_ENDIAN = 0 [nPx-1], . . . ,[nSx]| [nSx-1], . . ., [0]. MPU_WORD_ORDER_BIG_ENDIAN = 1 [0], . . . , [nEx-1]| [nEx], . . ., [nPx-1]. |--------. . .-------|-------------------. . .--------------------| | Exponent | Significand | |--------. . .-------|-------------------. . .--------------------| ^Sign bit ^(1.- implicit) size: nEx nSx. Exponent - смещенный порядок; Significand - мантисса; Общее количество слов - nEx + nSx; Бит целой (1.) - неявный. ***************************************************************/ /* Следующее не верно для real32 & real64 */ /*************************************************************** Количество бит выделяемое на Sign и Exponent в external e-type data struct. n - number of bits in external e-type data struct. ***************************************************************/ #define NEBITS(nb) ((__mpu_int32_t)(internal_ne(nb)*BITS_PER_EMUSHORT)) /*************************************************************** Количество бит выделяемое на Significand в external e-type data struct. n - number of bits in external e-type data struct. ***************************************************************/ #define NSBITS(nb) ((__mpu_int32_t)(internal_ns(nb)*BITS_PER_EMUSHORT)) /*********************************************************** Количество EMUSHORT порций в Internal e-type data struct. NOTE for real128 и более: InternalNP = InternalNE + InternalNS + 3(Sign, hgw, lgw). ExternalNE = InternalNE. ExternalNS = InternalNS. ExternalNP = InternalNE + InternalNS. ***********************************************************/ extern int internal_ne( int nb ); extern int internal_ns( int nb ); extern int internal_np( int nb ); extern void ei_cleaz ( EMUSHORT *ei, int nb ); extern void ei_cleazs ( EMUSHORT *ei, int nb ); extern void ei_ind ( EMUSHORT *ei, int nb ); extern int ei_isind ( EMUSHORT *ei, int nb ); extern void e_ind ( EMUSHORT *ee, int nb ); extern int e_isind ( EMUSHORT *ee, int nb ); extern void ei_nan ( EMUSHORT *ei, unsigned sign, int nb ); extern int ei_isnans ( EMUSHORT *ei, int nb ); extern void e_nan ( EMUSHORT *ee, unsigned sign, int nb ); extern int e_isnans ( EMUSHORT *ee, int nb ); extern void ei_nanmax ( EMUSHORT *ei, unsigned sign, int nb ); extern int ei_isnanmax ( EMUSHORT *ei, int nb ); extern void e_nanmax ( EMUSHORT *ee, unsigned sign, int nb ); extern int e_isnanmax ( EMUSHORT *ee, int nb ); extern void ei_nanmin ( EMUSHORT *ei, unsigned sign, int nb ); extern int ei_isnanmin ( EMUSHORT *ei, int nb ); extern void e_nanmin ( EMUSHORT *ee, unsigned sign, int nb ); extern int e_isnanmin ( EMUSHORT *ee, int nb ); extern void ei_infin ( EMUSHORT *ei, unsigned sign, int nb ); extern int ei_isinfin ( EMUSHORT *ei, int nb ); extern void e_infin ( EMUSHORT *ee, unsigned sign, int nb ); extern int e_isinfin ( EMUSHORT *ee, int nb ); extern void e_realmin ( EMUSHORT *ee, unsigned sign, int nb ); extern void e_realmax ( EMUSHORT *ee, unsigned sign, int nb ); extern void ei_signull ( EMUSHORT *ei, unsigned sign, int nb ); extern int ei_issignull ( EMUSHORT *ei, int nb ); extern void e_signull ( EMUSHORT *ee, unsigned sign, int nb ); extern int e_issignull ( EMUSHORT *ee, int nb ); extern void ei_neg ( EMUSHORT *ei, int nb ); extern int ei_isneg ( EMUSHORT *ei, int nb ); extern void e_neg ( EMUSHORT *ee, int nb ); extern int e_isneg ( EMUSHORT *ee, int nb ); extern void ei_abs ( EMUSHORT *ei, int nb ); extern void e_abs ( EMUSHORT *ee, int nb ); /*************************************************************** Functions for LONG INTEGER NUMBERS: */ /* SIGNED COMPARE TWO SIGNED INTEGER NUMBER if( a > b ) return( 1); if( a == b ) return( 0); if( a < b ) return( -1); */ extern int ei_cmpe ( EMUSHORT *a, EMUSHORT *b, int np ); /* SIGNED COMPARE A with ZERO if( a > 0 ) return( 1); if( a == 0 ) return( 0); if( a < 0 ) return( -1); */ extern int ei_cmp0e ( EMUSHORT *a, int np ); /* КОПИРОВАНИЕ БОЛЬШЕГО В МЕНЬШЕЕ (npa < npb) */ extern void ei_cpye_pack ( EMUSHORT *a, EMUSHORT *b, int npa, int npb ); /* КОПИРОВАНИЕ МЕНЬШЕГО В БОЛЬШЕЕ (npa >= npb) */ extern void ei_cpye_unpack ( EMUSHORT *a, EMUSHORT *b, int npa, int npb ); /* COPY UNSIGNED INTEGER NUMBER */ extern void ei_cpye ( EMUSHORT *a, EMUSHORT *b, int npa, int npb ); /* КОНВЕРТИРОВАНИЕ МЕНЬШЕГО В БОЛЬШЕЕ (npa >= npb) */ extern void ei_cvte_unpack ( EMUSHORT *a, EMUSHORT *b, int npa, int npb ); /* КОНВЕРТИРОВАНИЕ БОЛЬШЕГО В МЕНЬШЕЕ (npa < npb) */ extern void ei_cvte_pack ( EMUSHORT *a, EMUSHORT *b, int npa, int npb ); /* CONVERT SIGNED INTEGER NUMBER */ extern void ei_cvte ( EMUSHORT *a, EMUSHORT *b, int npa, int npb ); /* ADD INTEGER NUMBER */ extern void ei_adde ( EMUSHORT *c, EMUSHORT *a, EMUSHORT *b, int np ); /* INCrement INTEGER NUMBER */ extern void ei_ince ( EMUSHORT *c, EMUSHORT *a, int np ); /* SUB INTEGER NUMBER */ extern void ei_sube ( EMUSHORT *c, EMUSHORT *a, EMUSHORT *b, int np ); /* DECrement INTEGER NUMBER */ extern void ei_dece ( EMUSHORT *c, EMUSHORT *a, int np ); /* NEGATE Signed INTEGER NUMBER */ extern void ei_nege ( EMUSHORT *c, EMUSHORT *a, int np ); /* ADD INTEGER NUMBER */ extern void ei_ande ( EMUSHORT *c, EMUSHORT *a, EMUSHORT *b, int np ); /****************** СДВИГИ на b bits ******************/ /* SHIFT RIGHT */ extern void ei_shrn ( EMUSHORT *c, EMUSHORT *a, unsigned b, int np ); /* SHIFT LEFT */ extern void ei_shln ( EMUSHORT *c, EMUSHORT *a, unsigned b, int np ); /* End of Functions for LONG INTEGER NUMBERS. ***************************************************************/ extern void ei_shdown ( EMUSHORT *ei, unsigned sc, int nb ); extern void ei_shup ( EMUSHORT *ei, unsigned sc, int nb ); extern int ei_shift ( EMUSHORT *ei, int sc, int nb ); extern __mpu_int32_t ei_normalize ( EMUSHORT *ei, int nb ); extern void unpack ( EMUSHORT *ei, EMUSHORT *ee, int nb ); extern int ei_cmpm ( EMUSHORT *ai, EMUSHORT *bi, int nb ); extern void ei_addm ( EMUSHORT *ci, EMUSHORT *ai, EMUSHORT *bi, int nb ); extern void ei_subm ( EMUSHORT *ci, EMUSHORT *ai, EMUSHORT *bi, int nb ); extern int ei_divm ( EMUSHORT *quoti, EMUSHORT *numi, EMUSHORT *deni, int nb ); extern int ei_mulm ( EMUSHORT *prodi, EMUSHORT *numi, EMUSHORT *muli, int nb ); /*************************************************************** ROUNDOFF parameter register control. = == = = = регистр управления параметрами ОКРУГЛЕНИЯ. ***************************************************************/ #define NSBITS_DEFAULT 96 /* = NSBITS( NBR_128 ); */ extern int rndprc; extern void ei_mdenorm ( EMUSHORT *si, int lost, int subflag, EMUSHORT *exp, int rcontrol, int nb ); extern void pack ( EMUSHORT *ee, EMUSHORT *ei, int nb ); extern void ei_copy ( EMUSHORT *eia, EMUSHORT *eib, int nb ); extern void ei_copyzlgw ( EMUSHORT *eia, EMUSHORT *eib, int nb ); extern int ei_cmp ( EMUSHORT *ai, EMUSHORT *bi, int nb ); extern void ei_convert ( EMUSHORT *eia, EMUSHORT *eib, int nba, int nbb ); extern void ei_add ( EMUSHORT *eic, EMUSHORT *eia, EMUSHORT *eib, int nb ); extern void ei_sub ( EMUSHORT *eic, EMUSHORT *eia, EMUSHORT *eib, int nb ); extern void ei_div ( EMUSHORT *eic, EMUSHORT *eia, EMUSHORT *eib, int nb ); extern void ei_mul ( EMUSHORT *eic, EMUSHORT *eia, EMUSHORT *eib, int nb ); extern void ei_ltor ( EMUSHORT *ei, EMUSHORT *lp, int nb, int nlp ); extern void ei_ultor ( EMUSHORT *ei, EMUSHORT *lp, int nb, int nlp ); extern void ei_rtoul_frac ( EMUSHORT *lp, EMUSHORT *frac, EMUSHORT *ei, int nlp, int nb ); extern void ei_rtol_frac ( EMUSHORT *lp, EMUSHORT *frac, EMUSHORT *ei, int nlp, int nb ); /*************************************************************** GENERATORS OF CONSTANT: */ extern void _gen_zero ( EMUSHORT *eia, int nb ); extern void _gen_half ( EMUSHORT *eia, int nb ); extern void _gen_one ( EMUSHORT *eia, int nb ); extern void _gen_two ( EMUSHORT *eia, int nb ); extern void _gen_ten ( EMUSHORT *eia, int nb ); extern void _gen_mten ( EMUSHORT *eia, int nb ); extern void _gen_32 ( EMUSHORT *eia, int nb ); /* END GENERATORS OF CONSTANT. ***************************************************************/ extern void ei_remain ( EMUSHORT *eic, EMUSHORT *eiquot, EMUSHORT *eia, EMUSHORT *eib, int nb ); extern void ei_floor ( EMUSHORT *eic, EMUSHORT *eia, int nb ); extern void ei_ceil ( EMUSHORT *eic, EMUSHORT *eia, int nb ); extern void ei_round ( EMUSHORT *eic, EMUSHORT *eia, int nb ); extern void ei_frexp ( EMUSHORT *eis, EMUSHORT *lpexp, EMUSHORT *eia, int nlp, int nb ); extern void ei_ldexp ( EMUSHORT *eic, EMUSHORT *lppwr2, EMUSHORT *eia, int nlp, int nb ); extern void ei_logb ( EMUSHORT *lpbase2, EMUSHORT *eia, int nlp, int nb ); extern void ei_sqrt ( EMUSHORT *eic, EMUSHORT *eia, int nb ); #ifdef __cplusplus } /* ... extern "C" */ #endif #endif /* __MPU_REAL_H */