/***************************************************************
__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 */