Subversion Repositories HelenOS

Rev

Rev 731 | Rev 828 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2005 Josef Cejka
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. #include<sftypes.h>
  30. #include<add.h>
  31. #include<comparison.h>
  32.  
  33. float32 divFloat32(float32 a, float32 b)
  34. {
  35.     float32 result;
  36.     __s32 aexp, bexp, cexp;
  37.     __u64 afrac, bfrac, cfrac;
  38.    
  39.     result.parts.sign = a.parts.sign ^ b.parts.sign;
  40.    
  41.     if (isFloat32NaN(a)) {
  42.         if (isFloat32SigNaN(a)) {
  43.             /*FIXME: SigNaN*/
  44.         }
  45.         /*NaN*/
  46.         return a;
  47.     }
  48.    
  49.     if (isFloat32NaN(b)) {
  50.         if (isFloat32SigNaN(b)) {
  51.             /*FIXME: SigNaN*/
  52.         }
  53.         /*NaN*/
  54.         return b;
  55.     }
  56.    
  57.     if (isFloat32Infinity(a)) {
  58.         if (isFloat32Infinity(b)) {
  59.             /*FIXME: inf / inf */
  60.             result.binary = FLOAT32_NAN;
  61.             return result;
  62.         }
  63.         /* inf / num */
  64.         result.parts.exp = a.parts.exp;
  65.         result.parts.fraction = a.parts.fraction;
  66.         return result;
  67.     }
  68.  
  69.     if (isFloat32Infinity(b)) {
  70.         if (isFloat32Zero(a)) {
  71.             /* FIXME 0 / inf */
  72.             result.parts.exp = 0;
  73.             result.parts.fraction = 0;
  74.             return result;
  75.         }
  76.         /* FIXME: num / inf*/
  77.         result.parts.exp = 0;
  78.         result.parts.fraction = 0;
  79.         return result;
  80.     }
  81.    
  82.     if (isFloat32Zero(b)) {
  83.         if (isFloat32Zero(a)) {
  84.             /*FIXME: 0 / 0*/
  85.             result.binary = FLOAT32_NAN;
  86.             return result;
  87.         }
  88.         /* FIXME: division by zero */
  89.         result.parts.exp = 0;
  90.         result.parts.fraction = 0;
  91.         return result;
  92.     }
  93.  
  94.    
  95.     afrac = a.parts.fraction;
  96.     aexp = a.parts.exp;
  97.     bfrac = b.parts.fraction;
  98.     bexp = b.parts.exp;
  99.    
  100.     /* denormalized numbers */
  101.     if (aexp == 0) {
  102.         if (afrac == 0) {
  103.         result.parts.exp = 0;
  104.         result.parts.fraction = 0;
  105.         return result;
  106.         }
  107.         /* normalize it*/
  108.        
  109.         afrac <<= 1;
  110.             /* afrac is nonzero => it must stop */ 
  111.         while (! (afrac & FLOAT32_HIDDEN_BIT_MASK) ) {
  112.             afrac <<= 1;
  113.             aexp--;
  114.         }
  115.     }
  116.  
  117.     if (bexp == 0) {
  118.         bfrac <<= 1;
  119.             /* bfrac is nonzero => it must stop */ 
  120.         while (! (bfrac & FLOAT32_HIDDEN_BIT_MASK) ) {
  121.             bfrac <<= 1;
  122.             bexp--;
  123.         }
  124.     }
  125.  
  126.     afrac = (afrac | FLOAT32_HIDDEN_BIT_MASK ) << (32 - FLOAT32_FRACTION_SIZE - 1 );
  127.     bfrac = (bfrac | FLOAT32_HIDDEN_BIT_MASK ) << (32 - FLOAT32_FRACTION_SIZE );
  128.  
  129.     if ( bfrac <= (afrac << 1) ) {
  130.         afrac >>= 1;
  131.         aexp++;
  132.     }
  133.    
  134.     cexp = aexp - bexp + FLOAT32_BIAS - 2;
  135.    
  136.     cfrac = (afrac << 32) / bfrac;
  137.     if ((  cfrac & 0x3F ) == 0) {
  138.         cfrac |= ( bfrac * cfrac != afrac << 32 );
  139.     }
  140.    
  141.     /* pack and round */
  142.    
  143.     /* TODO: find first nonzero digit and shift result and detect possibly underflow */
  144.     while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7 )))) {
  145.         cexp--;
  146.         cfrac <<= 1;
  147.             /* TODO: fix underflow */
  148.     };
  149.    
  150.    
  151.     cfrac += (0x1 << 6); /* FIXME: 7 is not sure*/
  152.    
  153.     if (cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
  154.         ++cexp;
  155.         cfrac >>= 1;
  156.         }  
  157.  
  158.     /* check overflow */
  159.     if (cexp >= FLOAT32_MAX_EXPONENT ) {
  160.         /* FIXME: overflow, return infinity */
  161.         result.parts.exp = FLOAT32_MAX_EXPONENT;
  162.         result.parts.fraction = 0;
  163.         return result;
  164.     }
  165.  
  166.     if (cexp < 0) {
  167.         /* FIXME: underflow */
  168.         result.parts.exp = 0;
  169.         if ((cexp + FLOAT32_FRACTION_SIZE) < 0) {
  170.             result.parts.fraction = 0;
  171.             return result;
  172.         }
  173.         cfrac >>= 1;
  174.         while (cexp < 0) {
  175.             cexp ++;
  176.             cfrac >>= 1;
  177.         }
  178.        
  179.     } else {
  180.         result.parts.exp = (__u32)cexp;
  181.     }
  182.    
  183.     result.parts.fraction = ((cfrac >> 6) & (~FLOAT32_HIDDEN_BIT_MASK));
  184.    
  185.     return result; 
  186. }
  187.  
  188.