home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c082_144 / 1.ddi / MATHSRC.ZIP / LDTRUNC.CAS < prev    next >
Encoding:
Text File  |  1992-06-10  |  3.8 KB  |  145 lines

  1. /*------------------------------------------------------------------------
  2.  * filename - ldtrunc.cas
  3.  *
  4.  * function(s)
  5.  *        __ldtrunc - internal function
  6.  *-----------------------------------------------------------------------*/
  7.  
  8. /*
  9.  *      C/C++ Run Time Library - Version 5.0
  10.  *
  11.  *      Copyright (c) 1987, 1992 by Borland International
  12.  *      All Rights Reserved.
  13.  *
  14.  */
  15.  
  16. #pragma inline
  17. #pragma warn -rvl
  18. #pragma warn -ret
  19. #include <errno.h>
  20. #include <_scanf.h>
  21.  
  22.  
  23. /*----------------------------------------------------------*
  24. double near pascal __ldtrunc(int flag, long double x, double xhuge);
  25.  
  26. __ldtrunc() is an internal TC library function which truncates a
  27. long double to a float (flag=0) or a double (flag=1), within the
  28. constraints of what can be done in a library function.  The
  29. argument is checked for underflow, which is flushed to 0, and
  30. overflowed, which is changed to xhuge.  In either case, the sign
  31. of x is attached to the result.  Otherwise, x is returned
  32. unchanged.  The global errno is set to ERANGE, if an overflow or
  33. underflow would have occurred.  No overflow or underflow
  34. exceptions are generated.
  35.  
  36. If flag = 0, it is suggested that xhuge = 1./0.
  37. If flag = 1, it is suggested that yhuge = HUGE_VAL.
  38.  
  39. *-----------------------------------------------------------*/
  40.  
  41. /*
  42.  
  43. Method:
  44.  
  45. The exponent (biased) in long double format is used to determine
  46. whether an overflow or underflow will occur.  This is quick and
  47. reliable, except for a few subtleties involving roundoff at the
  48. extreme exponents.
  49.  
  50. cutoff values:
  51.  
  52. largest normal double has biased exponent 43FEh in 10-byte format.
  53. smallest normal double has biased exponent 3C01h in 10-byte format.
  54. smallest denormal double has biased exponent 3BCDh in 10-byte format.
  55.  
  56. largest normal float has biased exponent 407Eh in 10-byte format.
  57. smallest normal float has biased exponent 3F81h in 10-byte format.
  58. smallest denormal float has biased exponent 3F6Ah in 10-byte format.
  59.  
  60. */
  61.  
  62.  
  63.  
  64. double near pascal __ldtrunc(int flag, long double x, double xhuge)
  65. {
  66.         volatile unsigned cword, cword2;
  67.         _CX = 0;
  68.  
  69. /* AX = overflow threshold, BX = underflow threshold */
  70. asm     mov     ax, 43FEh
  71. asm     mov     bx, 3BCDh
  72. asm     cmp     word ptr flag, 0
  73. asm     jne     start
  74. asm     mov     ax, 407Eh
  75. asm     mov     bx, 3F6Ah
  76. start:
  77.  
  78. asm     mov     dx, x[8]
  79. asm     shl     dx, 1
  80. asm     rcl     cx, 1
  81. asm     shr     dx, 1
  82. /* CX = sign bit, DX = biased exponent */
  83. /* let INF, NAN pass */
  84. asm     cmp     dx, 7FFFh
  85. asm     je      ret
  86. /* test for overflow */
  87. asm     cmp     dx, ax
  88. asm     je      hugex
  89. asm     jle     notinf
  90. /* overflow to HUGE_VAL with appropriate sign */
  91. asm     fld     qword ptr xhuge
  92.         goto ret1;
  93.  
  94. hugex:
  95. /* chop in borderline infinite case, to avoid overflow */
  96. asm     fstcw   cword
  97. asm     mov     ax, 0C00h
  98. asm     fwait
  99. asm     or      ax, cword
  100. asm     mov     cword2, ax
  101. asm     fldcw   cword2
  102. asm     fld     tbyte ptr x
  103. asm     cmp     word ptr flag, 0
  104. asm     jne     s1
  105. asm     fstp    dword ptr xhuge
  106. asm     fld     dword ptr xhuge
  107. asm     jmp     short s2
  108. s1:
  109. asm     fstp    qword ptr xhuge
  110. asm     fld     qword ptr xhuge
  111. s2:
  112. /* restore previous control word */
  113. asm     fldcw   cword
  114.         return;
  115.  
  116. notinf:
  117. /* test for +0 or -0 */
  118. asm     mov     ax, dx
  119. asm     or      ax, x[6]
  120. asm     or      ax, x[4]
  121. asm     or      ax, x[2]
  122. asm     or      ax, x[0]
  123. asm     jz      ret
  124.  
  125. /* test for underflow */
  126. asm     cmp     dx, bx
  127. asm     jge     ret
  128.  
  129. /* underflow to 0 with appropriate sign */
  130. asm     fldz
  131. ret1:
  132. asm     or      cx, cx
  133. asm     jz      ret0
  134. asm     fchs
  135. ret0:
  136.         errno = ERANGE;
  137.         return;
  138. ret:
  139.         return x;
  140. }
  141.  
  142. /* to guarantee scantod.cas code gets linked */
  143. /* need this for atof(), strtod() */
  144. asm     extrn __turboFloat : ABS
  145.