home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_11_09 / 1109074a < prev    next >
Text File  |  1993-04-10  |  10KB  |  406 lines

  1. /*-------------------------------------------------
  2.  
  3.         Module: FIXED.CPP
  4.       
  5.       Class: Fixed
  6.       
  7.       Description: A fixed point numerical
  8.       class that performs numerical operations
  9.       in a 15.16 bit signed format, using a signed
  10.       long as native storage.
  11.  
  12.       This format is capable of storing numbers
  13.       in a range of +32,767 to -32,768 in 1/65535ths
  14.       increments (approx. 0.0000153, or about 5
  15.       decimals of accuracy).
  16.       
  17.       
  18.       Revision History
  19. -----------------------------------------------------
  20.   Date      Name  Comment
  21. -----------------------------------------------------
  22.  
  23. Feb-16-93   rbf   Added the addProduct function
  24.  
  25. Nov-24-92   rbf   Initial Creation
  26.  
  27. ---------------------------------------------------*/
  28.  
  29. #include "FIXED.H"
  30. #include <stdio.h>
  31.  
  32.  
  33. /*-------------------------------------------------
  34.    default constructor
  35. --------------------------------------------------*/
  36.  
  37. Fixed::Fixed()
  38. {
  39.    fixeddata.long_rep = (FixedData)0;
  40. }
  41.  
  42.  
  43. /*-------------------------------------------------
  44.    default copy constructor
  45. --------------------------------------------------*/
  46.  
  47. Fixed::Fixed(const Fixed& rhs)
  48. {
  49.    fixeddata.long_rep = rhs.fixeddata.long_rep;
  50. }
  51.  
  52.  
  53. /*-------------------------------------------------
  54.    constructor taking a double
  55. --------------------------------------------------*/
  56.  
  57. Fixed::Fixed(double rhs)
  58. {
  59.    // shift it into the 2nd 16 bits-------+
  60.    //          round it---------+         |
  61.    //  then truncate it --+     |         |
  62.    //                     |     |         |
  63.    fixeddata.long_rep = (long)(0.5 + (rhs * 65536.0));
  64. }
  65.  
  66.  
  67. /*-------------------------------------------------
  68.    constructor taking an int
  69. --------------------------------------------------*/
  70.  
  71. Fixed::Fixed(int rhs)
  72. {
  73.    // shift it into the 2nd 16 bits
  74.    fixeddata.long_rep = (FixedData)rhs << 16;
  75. }
  76.  
  77.  
  78. /*------------------------------------------------
  79.    default assignment
  80. --------------------------------------------------*/
  81.  
  82. Fixed&   Fixed::operator=(const Fixed& rhs)
  83. {
  84.    fixeddata.long_rep = rhs.fixeddata.long_rep;
  85.  
  86.    return *this;
  87. }
  88.  
  89.  
  90.  
  91. /*------------------------------------------------
  92.    default destructor
  93. --------------------------------------------------*/
  94.  
  95. Fixed::~Fixed()
  96. {
  97.    ; // if there were something to destroy,
  98.      // we'd do it here
  99. }
  100.  
  101.  
  102.  
  103. /*------------------------------------------------
  104.    ostream output
  105. --------------------------------------------------*/
  106.  
  107. // describe how to output a fixed value
  108.  
  109. ostream& operator<<( ostream& s, Fixed& rhs )
  110. {
  111.    return ( s <<
  112.       (((double)rhs.fixeddata.long_rep) / 65536.0) );
  113. }
  114.  
  115.  
  116. /*-------------------------------------------------
  117.    addition operator
  118.    the order of the addition makes no difference
  119. --------------------------------------------------*/
  120.  
  121. Fixed operator+(const Fixed& lhs,
  122.       const Fixed& rhs)
  123. {
  124.    Fixed return_val(rhs);  // create a return temporary
  125.  
  126.    // add the data parts together
  127.    return_val.fixeddata.long_rep +=
  128.       lhs.fixeddata.long_rep;
  129.  
  130.    return return_val;
  131. }
  132.  
  133. /*-------------------------------------------------
  134.    subtraction operator
  135.    the order of the subtraction does make a difference
  136.    this function can be considered
  137.    "lhs.operator-( rhs )" for the
  138.    expression lhs-rhs
  139. --------------------------------------------------*/
  140.  
  141. Fixed operator-(const Fixed& lhs,
  142.       const Fixed& rhs)
  143. {
  144.    Fixed return_val(lhs);// create a return temporary
  145.  
  146.    // do the math, subtracting the
  147.    // left hand side from the right
  148.    return_val.fixeddata.long_rep -=
  149.          rhs.fixeddata.long_rep;
  150.  
  151.    return return_val;
  152. }
  153.  
  154.  
  155. /*-------------------------------------------------
  156.    multiplication operator
  157. --------------------------------------------------*/
  158.  
  159. // Force the use of the real assembler
  160. // for 386 instructions
  161. #pragma inline
  162. // quiet the compiler from complaining since
  163. // it can't read ASM code
  164. #pragma argsused
  165.  
  166. Fixed operator*(const Fixed& lhs, const Fixed& rhs)
  167. {
  168.    Fixed return_val;  // create a return temporary
  169.    
  170.    _asm{
  171.    .386C;   /* enable 386 instruction set */
  172.  
  173.    mov   bx,word ptr [bp+10]; /* get rhs's offset */
  174.    mov   eax,dword ptr [bx];  /* move rhs's 32 bits*/
  175.                               /* into eax */
  176.    mov   bx,word ptr [bp+8];  /* get this offset */
  177.    imul   dword ptr [bx];    /* mul by left hand side */
  178.  
  179.    /* if we overflow a 16 bit rational, */
  180.    /*   we don't check */
  181.  
  182.    mov   word ptr [bp-2],dx;    /* dx = high word of */
  183.                           /* return_value's pointer */
  184.  
  185.    /* shift the 32 bit fraction */
  186.    /* into a 16 bit (eax->ax) */
  187.    shr   eax,16;
  188.    mov   word ptr [bp-4],ax;    /* low word */
  189.    } /* asm */
  190.  
  191.    return return_val;
  192. }
  193.  
  194.  
  195. /*-------------------------------------------------
  196.    division operator
  197. --------------------------------------------------*/
  198.  
  199. // see comments for multiplication operator
  200. #pragma inline
  201. #pragma argsused
  202.  
  203. Fixed operator/(const Fixed& lhs, const Fixed& rhs)
  204. {
  205.  
  206.    Fixed temp = 0; // do our math in this temp on stack
  207.  
  208.    _asm{
  209.    .386C;   /* enable 386 instruction set */
  210.  
  211.    mov       eax,dword ptr [bp+8]; /* lhs */
  212.    sub     eax,eax;
  213.    mov     edx,[bp+10]; /* rhs */
  214.    shrd    eax,edx,16;   /* position result */
  215.    sar     edx,16;      /* in EAX */
  216.    idiv    dword ptr [bp+8]; /* lhs */
  217.    shld    edx,eax,16 /* whole part in DX */
  218.                /* fractional already in AX */
  219.    } /* asm */
  220.  
  221.    return Fixed(temp);
  222. }
  223.  
  224.  
  225. /*-------------------------------------------------
  226.    addProduct member function
  227. --------------------------------------------------*/
  228.  
  229. // see comments for multiplication operator
  230. #pragma inline
  231. #pragma argsused
  232.  
  233. void      Fixed::addProduct(const Fixed& rhs1,const Fixed& rhs2)
  234. {
  235.    _asm{
  236.    .386C;   /* enable 386 instruction set */
  237.  
  238.    /* word ptr [bp+4] is the address of *this data */
  239.    /* word ptr [bp+6] is the address of rhs1 data */
  240.    /* word ptr [bp+8] is the address of rhs2 data */
  241.  
  242.    mov   si,word ptr [bp+4] ; /* address of *this */
  243.  
  244.    mov   bx,  word ptr [bp+6]; /* get rhs1's offset */
  245.    mov   eax,dword ptr [bx];   /* move rhs1's 32 bits*/
  246.  
  247.    mov   bx,  word ptr [bp+8]; /* get rhs2's offset */
  248.    imul   dword ptr [bx];       /* mul rhs2 by rhs1 */
  249.  
  250.    /* if we overflow (as before) we don't check */
  251.  
  252.    /* shift the 32 bit fraction into a 16 bit (eax->ax) */
  253.    shr   eax,16;
  254.  
  255.    /* dx = high word (fractions) */
  256.    /* ax = low word (whole numbers) */
  257.    add   word ptr [si],ax;   
  258.    adc   word ptr [si+2],dx;
  259.  
  260.    } /* asm */
  261. }
  262.  
  263.  
  264. /*-------------------------------------------------
  265.    relational operator equal to
  266. --------------------------------------------------*/
  267.  
  268. int   operator==(const Fixed& lhs,
  269.       const Fixed& rhs)
  270. {
  271.    // compare the long values
  272.    return ( lhs.fixeddata.long_rep ==
  273.       rhs.fixeddata.long_rep );
  274. }
  275.  
  276.  
  277. /*-------------------------------------------------
  278.    relational operator not equal to
  279. --------------------------------------------------*/
  280.  
  281. int   operator!=(const Fixed& lhs,
  282.       const Fixed& rhs)
  283. {
  284.    // compare the long values
  285.    return ( lhs.fixeddata.long_rep !=
  286.       rhs.fixeddata.long_rep );
  287. }
  288.  
  289.  
  290. /*-------------------------------------------------
  291.    relational operator greater than
  292. --------------------------------------------------*/
  293.  
  294. int   operator>(const Fixed& lhs,
  295.       const Fixed& rhs)
  296. {
  297.    // compare the long values
  298.    return ( lhs.fixeddata.long_rep >
  299.       rhs.fixeddata.long_rep );
  300. }
  301.  
  302. /*-------------------------------------------------
  303.    relational operator less than
  304. --------------------------------------------------*/
  305.  
  306. int   operator<(const Fixed& lhs,
  307.       const Fixed& rhs)
  308. {
  309.    // compare the long values
  310.    return ( lhs.fixeddata.long_rep <
  311.       rhs.fixeddata.long_rep );
  312. }
  313.  
  314.  
  315. /*-------------------------------------------------
  316.    relational operator greater than equal to
  317. --------------------------------------------------*/
  318.  
  319. int   operator>=(const Fixed& lhs,
  320.       const Fixed& rhs)
  321. {
  322.    // compare the long values
  323.    return ( lhs.fixeddata.long_rep >=
  324.       rhs.fixeddata.long_rep );
  325. }
  326.  
  327.  
  328. /*-------------------------------------------------
  329.    relational operator less than equal to
  330. --------------------------------------------------*/
  331.  
  332. int   operator<=(const Fixed& lhs,
  333.       const Fixed& rhs)
  334. {
  335.    // compare the long values
  336.    return ( lhs.fixeddata.long_rep <=
  337.       rhs.fixeddata.long_rep );
  338. }
  339.  
  340.  
  341. /*-------------------------------------------------
  342.    compound assignment addition operator
  343. --------------------------------------------------*/
  344.  
  345. Fixed& Fixed::operator+=(const Fixed& rhs)
  346. {
  347.    fixeddata.long_rep += rhs.fixeddata.long_rep;
  348.    return *this;
  349. }
  350.  
  351.  
  352. /*-------------------------------------------------
  353.    compound assignment subtraction operator
  354. --------------------------------------------------*/
  355.  
  356. Fixed& Fixed::operator-=(const Fixed& rhs)
  357. {
  358.    fixeddata.long_rep -= rhs.fixeddata.long_rep;
  359.  
  360.    return *this;
  361. }
  362.  
  363. /*-------------------------------------------------
  364.    compound assignment multiplication operator
  365. --------------------------------------------------*/
  366.  
  367. Fixed& Fixed::operator*=(const Fixed& rhs)
  368. {
  369.    *this = *this * rhs;  // wimpy way of doing it.....
  370.  
  371.    return *this;
  372. }
  373.  
  374. /*-------------------------------------------------
  375.    compound assignment division operator
  376. --------------------------------------------------*/
  377.  
  378. Fixed& Fixed::operator/=(const Fixed& rhs)
  379. {
  380.    *this = *this / rhs;  // wimpy way of doing it.....
  381.  
  382.    return *this;
  383. }
  384.  
  385.  
  386. /*-------------------------------------------------
  387.    Unary plus operator
  388. --------------------------------------------------*/
  389. Fixed Fixed::operator+()
  390. {
  391.    return Fixed(*this);
  392. }
  393.  
  394. /*-------------------------------------------------
  395.    Unary minus operator
  396. --------------------------------------------------*/
  397. Fixed Fixed::operator-()
  398. {
  399.    Fixed return_val( *this );
  400.    return_val *= -1;
  401.    return return_val;
  402. }
  403.  
  404.  
  405.  
  406.