home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2337 / nextafterf.c < prev   
C/C++ Source or Header  |  1990-12-28  |  2KB  |  98 lines

  1. /*
  2. ** This file is part of the alternative 80386 math library and is
  3. ** covered by the GNU General Public license with my modification
  4. ** as noted in the README file that accompanied this file.
  5. **
  6. ** Copyright 1990 G. Geers
  7. **
  8. ** A mix of C and assembler - well I've got the functions so I might 
  9. ** as well use them!
  10. **
  11. */
  12.  
  13. #include "fpumath.h"
  14.  
  15. asm(".align 4");
  16. asm(".Lulp:");
  17. asm(".double 5.9604644775390625e-08");
  18.  
  19. asm(".align 4");
  20. asm(".Lulpup:");
  21. asm(".double 1.1920928955078125e-07");
  22.  
  23. float
  24. nextafterf(float x, float y)
  25. {
  26.     asm("subl $8, %esp");
  27.  
  28.     if (isnanf(x) || isnanf(y))
  29.         return(quiet_nanf(1.0));
  30.  
  31.     if (isinff(x))
  32.         if (y > x)
  33.             return(-max_normalf());
  34.         else
  35.         if (y < x)
  36.             return(max_normalf());
  37.  
  38.     if (x == 0.0) {
  39.         if (y > 0.0)
  40.             return(min_subnormalf());
  41.         else
  42.             return(-min_subnormalf());
  43.     }
  44.  
  45.     if (isnormalf(x)) {
  46.         if ((x == min_normalf()) && y < x)
  47.             return(max_subnormalf());
  48.  
  49.         if ((x == max_normalf()) && y > x)
  50.             return(infinityf());
  51.  
  52.         if ((x == -max_normalf()) && y < x)
  53.             return(-infinityf());
  54.  
  55.         asm("movl 8(%ebp), %eax");
  56.         asm("andl $0x7f800000, %eax");
  57.         asm("movl %eax, -8(%ebp)");
  58.         asm("fincstp");
  59.  
  60.         if (fabsf(x) <= 2.0 && y < x) 
  61.             asm("fldl .Lulp");
  62.         else
  63.             asm("fldl .Lulpup");
  64.  
  65.         asm("flds -8(%ebp)");
  66.         asm("fmulp");
  67.  
  68.         if (y > x) {
  69.             asm("flds 8(%ebp)");
  70.             asm("faddp");
  71.             asm("leave");
  72.             asm("ret");
  73.         }
  74.         if (y < x) {
  75.             asm("flds 8(%ebp)");
  76.             asm("fsubp");
  77.             asm("leave");
  78.             asm("ret");
  79.         }
  80.     }
  81.     else
  82.     if (issubnormalf(x)) {
  83.         if ((x == max_subnormalf()) && y > x)
  84.             return(min_normalf());
  85.  
  86.         if ((x == -max_subnormalf()) && y < x)
  87.             return(-min_normalf());
  88.  
  89.         if (y > x) 
  90.             return(x + min_subnormalf());
  91.  
  92.         if (y < x)
  93.             return(x - min_subnormalf());
  94.     }
  95.     
  96.     return(x);
  97. }
  98.