Math Processor Unit Library

libmpu – library of arithmetic functions for integer, real, and complex numbers of increased digit capacity

16 Commits   0 Branches   2 Tags

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