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_EMUTYPE.H

       Macro definitions of types EMUSHORT, EMULONG.
       Bits operations MACRO for EMUSHORT data type.

       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_EMUTYPE_H
#define   __MPU_EMUTYPE_H

#ifdef  __cplusplus
extern "C" {
#endif


/***************************************************************
  MACRO FOR REAL ARITHMETIC
 ***************************************************************/
/*
  NOTE:
  ====
  SIZE_OF_EMUPART <= SIZE_OF_EMUSHORT:
  -----------------------------------
    if SIZE_OF_EMUSHORT == 4 then SIZE_OF_EMUPART == 4 ;
    if SIZE_OF_EMUSHORT == 8 then SIZE_OF_EMUPART == 4 .
 */
#define PART_MASK_SIGN     EMUPART_C( 0x80000000 )
/* Mask of Exponent (hight part) */
#define PART_HIGHT_EXP     EMUPART_C( 0x7fffffff )
/* Exponent of 1.0 (hight part) */
#define PART_HIGHT_EXONE   EMUPART_C( 0x3fffffff )
/* Significand of -1.IND with implisit 1.0 (hight part) */
#define PART_HIGHT_EI_IND  EMUPART_C( 0xc0000000 )
#define PART_HIGHT_BYTE    EMUPART_C( 0xff000000 )
#define PART_MASK_ALL_BITS EMUPART_C( 0xffffffff )

/***************************************************************
  EMUPARTSIZE computes the number of EMUPARTs needed
  to store n bits;
 ***************************************************************/
#define EMUPARTSIZE(n) (((n)+(BITS_PER_EMUPART-1))/BITS_PER_EMUPART)


/***************************************************************
  Calculate the number of EMUSHORT partions in integer data
  types, or real data types.

  For example:
     NP_8   - number of (EMUSHORT) partions in the int8 type;
     NP_256 - number of (EMUSHORT) partions in the int256 type.
 ***************************************************************/
#define MASK_CARRY    EMULONG_C( 0x100000000 )
#define MASK_SIGN     EMUSHORT_C( 0x80000000 )
/* Mask of Exponent (hight part) */
#define HIGHT_EXP     EMUSHORT_C( 0x7fffffff )
/* Exponent of 1.0 (hight part) */
#define HIGHT_EXONE   EMUSHORT_C( 0x3fffffff )
/* Exponent of 2.0 (hight part) */
#define HIGHT_EXTWO   EMUSHORT_C( 0x40000000 )
/* MAX Exponent of 10^[a power of two] (hight part) */
#define HIGHT_EXMAX_P EMUSHORT_C( 0x10000000 )
/* Significand of 10^1 (hight part) */
#define HIGHT_M_TEN   EMUSHORT_C( 0xa0000000 )
/* Significand of 10^-1 (hight part) */
#define HIGHT_M_MTEN  EMUSHORT_C( 0xcccccccc )
/* Significand of -1.IND with implisit 1.0 (hight part) */
#define HIGHT_EI_IND  EMUSHORT_C( 0xc0000000 )
#define HIGHT_BYTE    EMUSHORT_C( 0xff000000 )
#define MASK_ALL_BITS EMUSHORT_C( 0xffffffff )
/* zise in BITS   EMUSHORTS */
/*         ====== ========= */
#define NP_8              0
#define NP_16             0
#define NP_32             1
#define NP_64             2
#define NP_128            4
#define NP_256            8
#define NP_512           16
#define NP_1024          32
#define NP_2048          64
#define NP_4096         128
#define NP_8192         256
#define NP_16384        512
#define NP_32768       1024
#define NP_65536       2048 /* 8192 Kbytes  */
#define NP_131072      4096 /* 16384 Kbytes */
#define NP_MAX         4096
#define NP_MAX_2       2048 /* NP_MAX / 2   */

/********************************************************************
  РАЗМЕРЫ ТИПОВ ДАННЫХ ПО КОЛИЧЕСТВУ СЛОВ(ПОРЦИЙ-Part) ТИПА EMUSHORT
 ********************************************************************/
/**********
  INTEGER:
 */
#define NPI_8       NP_8
#define NPI_16      NP_16
#define NPI_32      NP_32
#define NPI_64      NP_64
#define NPI_128     NP_128
#define NPI_256     NP_256
#define NPI_512     NP_512
#define NPI_1024    NP_1024
#define NPI_2048    NP_2048
#define NPI_4096    NP_4096
#define NPI_8192    NP_8192
#define NPI_16384   NP_16384
#define NPI_32768   NP_32768
#define NPI_65536   NP_65536
#define NPI_131072  NP_131072
#define NPI_MAX     NP_MAX
#define NPI_MAX_2   NP_MAX_2

/*******
  REAL:
 */
#define NPR_32      NP_32
#define NPR_64      NP_64
#define NPR_128     NP_128
#define NPR_256     NP_256
#define NPR_512     NP_512
#define NPR_1024    NP_1024
#define NPR_2048    NP_2048
#define NPR_4096    NP_4096
#define NPR_8192    NP_8192
#define NPR_16384   NP_16384
#define NPR_32768   NP_32768
#define NPR_65536   NP_65536
#define NPR_131072  NP_131072
#define NPR_MAX     NP_MAX
#define NPR_MAX_2   NP_MAX_2


/********************************************************************
  РАЗМЕРЫ ТИПОВ ДАННЫХ ПО КОЛИЧЕСТВУ БИТ
 ********************************************************************/
/**********
  INTEGER:
 */
#define NBI_8        8
#define NBI_16       16
#define NBI_32       32
#define NBI_64       64
#define NBI_128      128
#define NBI_256      256
#define NBI_512      512
#define NBI_1024     1024
#define NBI_2048     2048
#define NBI_4096     4096
#define NBI_8192     8192
#define NBI_16384    16384
#define NBI_32768    32768
#define NBI_65536    65536
#define NBI_131072   131072
#define NBI_MAX      131072
#define NBI_MAX_2    65536

/*******
  REAL:
 */
#define NBR_32      32
#define NBR_64      64
#define NBR_128     128
#define NBR_256     256
#define NBR_512     512
#define NBR_1024    1024
#define NBR_2048    2048
#define NBR_4096    4096
#define NBR_8192    8192
#define NBR_16384   16384
#define NBR_32768   32768
#define NBR_65536   65536
#define NBR_131072  131072
#define NBR_MAX     131072
#define NBR_MAX_2   65536


/*********************************************************
  REAL Internal e-type:
  --------------------

  SIZE of Exponent in EMUSHORT partitions:
 */
#define NPIE_32        (NBR_32/BITS_PER_EMUSHORT)
#define NPIE_64        (NBR_32/BITS_PER_EMUSHORT)
#define NPIE_128       (NBR_32/BITS_PER_EMUSHORT)
#define NPIE_256       (NBR_32/BITS_PER_EMUSHORT)
#define NPIE_512       (NBR_64/BITS_PER_EMUSHORT)
#define NPIE_1024      (NBR_64/BITS_PER_EMUSHORT)
#define NPIE_2048     (NBR_128/BITS_PER_EMUSHORT)
#define NPIE_4096     (NBR_128/BITS_PER_EMUSHORT)
#define NPIE_8192     (NBR_256/BITS_PER_EMUSHORT)
#define NPIE_16384    (NBR_256/BITS_PER_EMUSHORT)
#define NPIE_32768    (NBR_512/BITS_PER_EMUSHORT)
#define NPIE_65536    (NBR_512/BITS_PER_EMUSHORT)
#define NPIE_131072  (NBR_1024/BITS_PER_EMUSHORT)
#define NPIE_MAX        NPIE_131072

/*********************************************************
  REAL Internal e-type:
  --------------------

  SIZE of Internal e-type number in EMUSHORT partitions:
 */
#define NPIR_32         (NBR_128/BITS_PER_EMUSHORT+3)
#define NPIR_64         (NBR_128/BITS_PER_EMUSHORT+3)
#define NPIR_128        (NBR_128/BITS_PER_EMUSHORT+3)
#define NPIR_256        (NBR_256/BITS_PER_EMUSHORT+3)
#define NPIR_512        (NBR_512/BITS_PER_EMUSHORT+3)
#define NPIR_1024      (NBR_1024/BITS_PER_EMUSHORT+3)
#define NPIR_2048      (NBR_2048/BITS_PER_EMUSHORT+3)
#define NPIR_4096      (NBR_4096/BITS_PER_EMUSHORT+3)
#define NPIR_8192      (NBR_8192/BITS_PER_EMUSHORT+3)
#define NPIR_16384    (NBR_16384/BITS_PER_EMUSHORT+3)
#define NPIR_32768    (NBR_32768/BITS_PER_EMUSHORT+3)
#define NPIR_65536    (NBR_65536/BITS_PER_EMUSHORT+3)
#define NPIR_131072  (NBR_131072/BITS_PER_EMUSHORT+3)
#define NPIR_MAX         NPIR_131072


/*************************************************************************
  Макроопределения для битовых операций над типом EMUSHORT.
 *************************************************************************/

/*************************************************************************
  Machine-dependent definitions the following definitions are for the
  Tahoe they might have to be changed for other machines.

  BITS_PER_EMUSHORT is the number of bits in a EMUSHORT data type;
  type EMUSHORT is smaller or equal a C (language) unsigned.

  EMUSHORTSIZE computes the number of EMUSHORTs needed to store n bits;
  BIT          returns the value of the n-th bit
               starting from r (0-indexed);
  SET_BIT      sets the n-th bit starting from r (0-indexed);
  INVERT_BIT   convert the n-th bit starting from r (0-indexed).

 *************************************************************************/

#if BITS_PER_EMUSHORT == 64
#define POW2          6
/*************************************************************************

     ...                              r[0]
    --|------------------------------------------------------------------|
      | 0000000000000000000000000000000000000000000000000000000000000000 |
    --|------------------------------------------------------------------|
    n: 63                                                               0

*************************************************************************/
#else /* not (BITS_PER_EMUSHORT == 64) */
#if BITS_PER_EMUSHORT == 32
#define POW2          5
/*************************************************************************

  ...             r[1]                                r[0]
 --|----------------------------------|----------------------------------|
   | 00000000000000000000000000000000 | 00000000000000000000000000000000 |
 --|----------------------------------|----------------------------------|
 n: 63                              32 31                               0

 *************************************************************************/
#else /* not (BITS_PER_EMUSHORT == 32) */
#if BITS_PER_EMUSHORT == 16
#define POW2          4
/*************************************************************************

                  ...      r[1]               r[0]
                 --|------------------|------------------|
                   | 0000000000000000 | 0000000000000000 |
                 --|------------------|------------------|
                 n: 31              16 15               0

 *************************************************************************/
#else /* not (BITS_PER_EMUSHORT == 16) */
#define __NOT_INCLUDE_BIT_MACRO 1
#define EMU_NON_COMPILE
#endif /* BITS_PER_EMUSHORT == 16 */
#endif /* BITS_PER_EMUSHORT == 32 */
#endif /* BITS_PER_EMUSHORT == 64 */

#if     !defined( __NOT_INCLUDE_BIT_MACRO )
#define EMUSHORTSIZE(n)  (((n)+(BITS_PER_EMUSHORT-1))/BITS_PER_EMUSHORT)
#define BIT(r,n)         ((((r)[(n)>>POW2])>>((n)&(BITS_PER_EMUSHORT-1)))&1)
#define SET_BIT(r,n)     ((r)[(n)>>POW2]|=((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1))))
#define INVERT_BIT(r,n)  ((r)[(n)>>POW2]^=(((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1)))))
#if MPU_WORD_ORDER_BIG_ENDIAN == 1
#define ORDER_BIT(r,n,np)         ((((r)[((np-1)-((n)>>POW2))])>>((n)&(BITS_PER_EMUSHORT-1)))&1)
#define ORDER_SETBIT(r,n,np)      ((r)[((np-1)-((n)>>POW2))]|=((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1))))
#define ORDER_INVERT_BIT(r,n,np)  ((r)[((np-1)-((n)>>POW2))]^=(((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1)))))
#else
#define ORDER_BIT(r,n,np)         ((((r)[(n)>>POW2])>>((n)&(BITS_PER_EMUSHORT-1)))&1)
#define ORDER_SETBIT(r,n,np)      ((r)[(n)>>POW2]|=((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1))))
#define ORDER_INVERT_BIT(r,n,np)  ((r)[(n)>>POW2]^=(((EMUSHORT)1<<((n)&(BITS_PER_EMUSHORT-1)))))
#endif
#endif
/*************************************************************************
  Определения BIT(r,n), SET_BIT(r,n), INVERT_BIT(r,n) требуют, чтобы по
  адресу &r[0] находилась младшая порция набора бит. СЛЕДОВАТЕЛЬНО, ЕСЛИ
  полное количество бит укладывается в BITS_PER_EMUSHORT, то макросы
  будут работать корректно при любом значении BIG_ENDIAN. ЕСЛИ полное
  количество бит не укладывается в BITS_PER_EMUSHORT, то макросы будут
  работать корректно только при BIG_ENDIAN = 0. ДАННОЕ ОБСТОЯТЕЛЬСТВО
  НАДО УЧИТЫВАТЬ ПРИ ИСПОЛЬЗОВАНИИ BIT(r,n), SET_BIT(r,n),
  INVERT_BIT(r,n) в операциях над целыми и вещественными числами.
  НАПРИМЕР, при BIG_ENDIAN = 1 в массивах EMUSHORT x[NP] младшая часть
  числа расположена в x[NP-1], а старшая в x[0]; СЛЕДОВАТЕЛЬНО, если надо
  узнать значение 78 бита (например), то перед применением макроса
  BIT(x,78) НЕОБХОДИМО поменять расположение ПОРЦИЙ EMUSHORT в числе,
  расположенном по адресу x (!!!ИМЕННО РАСПОЛОЖЕНИЕ ПОРЦИЙ EMUSHORT,
  А НЕ БАЙТ: т.к. макросы обращаются к порциям).

  ЕСЛИ константа MPU_WORD_ORDER_BIG_ENDIAN установлена в 1, то для
  определения значения n-го бита в длинном числе можно применить
  определение ORDER_BIT(r,n,np), где np - количество EMUSHORT-порций
  в числе. Макросы ORDER_BIT(r,n,np), ORDER_SET_BIT(r,n,np),
  ORDER_INVERT_BIT(r,n,np) работают при любой ориентации слов
  (big-endian or little-endian). Если MPU_WORD_ORDER_BIG_ENDIAN == 0,
  то параметр np просто не используется.
 *************************************************************************/



#ifdef  __cplusplus
}   /* ... extern "C" */
#endif

#endif /* __MPU_EMUTYPE_H */