Subversion Repositories HelenOS-historic

Rev

Rev 737 | 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<mul.h>
  31. #include<comparison.h>
  32.  
  33. /** Multiply two 32 bit float numbers
  34.  *
  35.  */
  36. float32 mulFloat32(float32 a, float32 b)
  37. {
  38.     float32 result;
  39.     __u64 mant1, mant2;
  40.     __s32 exp;
  41.  
  42.     result.parts.sign = a.parts.sign ^ b.parts.sign;
  43.    
  44.     if ((isFloat32NaN(a))||(isFloat32NaN(b))) {
  45.         /* TODO: fix SigNaNs */
  46.         if (isFloat32SigNaN(a)) {
  47.             result.parts.mantisa = a.parts.mantisa;
  48.             result.parts.exp = a.parts.exp;
  49.             return result;
  50.         };
  51.         if (isFloat32SigNaN(b)) { /* TODO: fix SigNaN */
  52.             result.parts.mantisa = b.parts.mantisa;
  53.             result.parts.exp = b.parts.exp;
  54.             return result;
  55.         };
  56.         /* set NaN as result */
  57.         result.parts.mantisa = 0x1;
  58.         result.parts.exp = 0xFF;
  59.         return result;
  60.     };
  61.        
  62.     if (isFloat32Infinity(a)) {
  63.         if (isFloat32Zero(b)) {
  64.             /* FIXME: zero * infinity */
  65.             result.parts.mantisa = 0x1;
  66.             result.parts.exp = 0xFF;
  67.             return result;
  68.         }
  69.         result.parts.mantisa = a.parts.mantisa;
  70.         result.parts.exp = a.parts.exp;
  71.         return result;
  72.     }
  73.  
  74.     if (isFloat32Infinity(b)) {
  75.         if (isFloat32Zero(a)) {
  76.             /* FIXME: zero * infinity */
  77.             result.parts.mantisa = 0x1;
  78.             result.parts.exp = 0xFF;
  79.             return result;
  80.         }
  81.         result.parts.mantisa = b.parts.mantisa;
  82.         result.parts.exp = b.parts.exp;
  83.         return result;
  84.     }
  85.  
  86.     /* exp is signed so we can easy detect underflow */
  87.     exp = a.parts.exp + b.parts.exp;
  88.     exp -= FLOAT32_BIAS;
  89.    
  90.     if (exp >= 0xFF ) {
  91.         /* FIXME: overflow */
  92.         /* set infinity as result */
  93.         result.parts.mantisa = 0x0;
  94.         result.parts.exp = 0xFF;
  95.         return result;
  96.     };
  97.    
  98.     if (exp < 0) {
  99.         /* FIXME: underflow */
  100.         /* return signed zero */
  101.         result.parts.mantisa = 0x0;
  102.         result.parts.exp = 0x0;
  103.         return result;
  104.     };
  105.    
  106.     mant1 = a.parts.mantisa;
  107.     if (a.parts.exp>0) {
  108.         mant1 |= 0x800000;
  109.     } else {
  110.         ++exp;
  111.     };
  112.    
  113.     mant2 = b.parts.mantisa;
  114.     if (b.parts.exp>0) {
  115.         mant2 |= 0x800000;
  116.     } else {
  117.         ++exp;
  118.     };
  119.  
  120.     mant1 <<= 1; /* one bit space for rounding */
  121.  
  122.     mant1 = mant1 * mant2;
  123. /* round and return */
  124.    
  125.     while ((exp < 0xFF )&&(mant1 > 0x1FFFFFF )) {
  126.         /* 0xFFFFFF is 23 bits of mantisa + one more for hidden bit (all shifted 1 bit left)*/
  127.         ++exp;
  128.         mant1 >>= 1;
  129.     };
  130.  
  131.     /* rounding */
  132.     //++mant1; /* FIXME: not works - without it is ok */
  133.     mant1 >>= 1; /* shift off rounding space */
  134.    
  135.     if ((exp < 0xFF )&&(mant1 > 0xFFFFFF )) {
  136.         ++exp;
  137.         mant1 >>= 1;
  138.     };
  139.  
  140.     if (exp >= 0xFF ) {
  141.         /* TODO: fix overflow */
  142.         /* return infinity*/
  143.         result.parts.exp = 0xFF;
  144.         result.parts.mantisa = 0x0;
  145.         return result;
  146.     }
  147.    
  148.     exp -= FLOAT32_MANTISA_SIZE;
  149.  
  150.     if (exp <= FLOAT32_MANTISA_SIZE) {
  151.         /* denormalized number */
  152.         mant1 >>= 1; /* denormalize */
  153.         while ((mant1 > 0) && (exp < 0)) {
  154.             mant1 >>= 1;
  155.             ++exp;
  156.         };
  157.         if (mant1 == 0) {
  158.             /* FIXME : underflow */
  159.         result.parts.exp = 0;
  160.         result.parts.mantisa = 0;
  161.         return result;
  162.         };
  163.     };
  164.     result.parts.exp = exp;
  165.     result.parts.mantisa = mant1 & 0x7FFFFF;
  166.    
  167.     return result; 
  168.    
  169. }
  170.  
  171.  
  172.  
  173.