Subversion Repositories HelenOS-historic

Rev

Rev 732 | Rev 804 | 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. /** Add two Float32 numbers with same signs
  34.  */
  35. float32 addFloat32(float32 a, float32 b)
  36. {
  37.     int expdiff;
  38.     __u32 exp1, exp2,mant1, mant2;
  39.    
  40.     expdiff = a.parts.exp - b.parts.exp;
  41.     if (expdiff < 0) {
  42.         if (isFloat32NaN(b)) {
  43.             //TODO: fix SigNaN
  44.             if (isFloat32SigNaN(b)) {
  45.             };
  46.  
  47.             return b;
  48.         };
  49.        
  50.         if (b.parts.exp == FLOAT32_MAX_EXPONENT) {
  51.             return b;
  52.         }
  53.        
  54.         mant1 = b.parts.mantisa;
  55.         exp1 = b.parts.exp;
  56.         mant2 = a.parts.mantisa;
  57.         exp2 = a.parts.exp;
  58.         expdiff *= -1;
  59.     } else {
  60.         if (isFloat32NaN(a)) {
  61.             //TODO: fix SigNaN
  62.             if (isFloat32SigNaN(a) || isFloat32SigNaN(b)) {
  63.             };
  64.             return a;
  65.         };
  66.        
  67.         if (a.parts.exp == FLOAT32_MAX_EXPONENT) {
  68.             return a;
  69.         }
  70.        
  71.         mant1 = a.parts.mantisa;
  72.         exp1 = a.parts.exp;
  73.         mant2 = b.parts.mantisa;
  74.         exp2 = b.parts.exp;
  75.     };
  76.    
  77.     if (exp1 == 0) {
  78.         /* both are denormalized */
  79.         mant1 += mant2;
  80.         if (mant1 & FLOAT32_HIDDEN_BIT_MASK ) {
  81.             /* result is not denormalized */
  82.             a.parts.exp = 1;
  83.         };
  84.         a.parts.mantisa = mant1;
  85.         return a;
  86.     };
  87.    
  88.     mant1 |= FLOAT32_HIDDEN_BIT_MASK; //add hidden bit
  89.  
  90.     if (exp2 == 0) {
  91.         /* second operand is denormalized */
  92.         --expdiff; 
  93.     } else {
  94.         /* add hidden bit to second operand */
  95.         mant2 |= FLOAT32_HIDDEN_BIT_MASK;
  96.     };
  97.    
  98.     /* create some space for rounding */
  99.     mant1 <<= 6;
  100.     mant2 <<= 6;
  101.    
  102.     if (expdiff > (FLOAT32_MANTISA_SIZE + 1) ) {
  103.          goto done;
  104.          };
  105.    
  106.     mant2 >>= expdiff;
  107.     mant1 += mant2;
  108. done:
  109.     if (mant1 & (FLOAT32_HIDDEN_BIT_MASK << 7) ) {
  110.         ++exp1;
  111.         mant1 >>= 1;
  112.     };
  113.    
  114.     /* rounding - if first bit after mantisa is set then round up */
  115.     mant1 += (0x1 << 5);
  116.    
  117.     if (mant1 & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
  118.         ++exp1;
  119.         mant1 >>= 1;
  120.     };
  121.    
  122.     a.parts.exp = exp1;
  123.    
  124.     /*Clear hidden bit and shift */
  125.     a.parts.mantisa = ((mant1 >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)) ;
  126.     return a;
  127. }
  128.  
  129.  
  130. /** Add two Float64 numbers with same signs
  131.  */
  132. float64 addFloat64(float64 a, float64 b)
  133. {
  134.     int expdiff;
  135.     __u32 exp1, exp2;
  136.     __u64 mant1, mant2;
  137.    
  138.     expdiff = a.parts.exp - b.parts.exp;
  139.     if (expdiff < 0) {
  140.         if (isFloat64NaN(b)) {
  141.             //TODO: fix SigNaN
  142.             if (isFloat64SigNaN(b)) {
  143.             };
  144.  
  145.             return b;
  146.         };
  147.        
  148.         /* b is infinity and a not */  
  149.         if (b.parts.exp == FLOAT64_MAX_EXPONENT ) {
  150.             return b;
  151.         }
  152.        
  153.         mant1 = b.parts.mantisa;
  154.         exp1 = b.parts.exp;
  155.         mant2 = a.parts.mantisa;
  156.         exp2 = a.parts.exp;
  157.         expdiff *= -1;
  158.     } else {
  159.         if (isFloat64NaN(a)) {
  160.             //TODO: fix SigNaN
  161.             if (isFloat64SigNaN(a) || isFloat64SigNaN(b)) {
  162.             };
  163.             return a;
  164.         };
  165.        
  166.         /* a is infinity and b not */
  167.         if (a.parts.exp == FLOAT64_MAX_EXPONENT ) {
  168.             return a;
  169.         }
  170.        
  171.         mant1 = a.parts.mantisa;
  172.         exp1 = a.parts.exp;
  173.         mant2 = b.parts.mantisa;
  174.         exp2 = b.parts.exp;
  175.     };
  176.    
  177.     if (exp1 == 0) {
  178.         /* both are denormalized */
  179.         mant1 += mant2;
  180.         if (mant1 & FLOAT64_HIDDEN_BIT_MASK) {
  181.             /* result is not denormalized */
  182.             a.parts.exp = 1;
  183.         };
  184.         a.parts.mantisa = mant1;
  185.         return a;
  186.     };
  187.    
  188.     /* add hidden bit - mant1 is sure not denormalized */
  189.     mant1 |= FLOAT64_HIDDEN_BIT_MASK;
  190.  
  191.     /* second operand ... */
  192.     if (exp2 == 0) {
  193.         /* ... is denormalized */
  194.         --expdiff; 
  195.     } else {
  196.         /* is not denormalized */
  197.         mant2 |= FLOAT64_HIDDEN_BIT_MASK;
  198.     };
  199.    
  200.     /* create some space for rounding */
  201.     mant1 <<= 6;
  202.     mant2 <<= 6;
  203.    
  204.     if (expdiff > (FLOAT64_MANTISA_SIZE + 1) ) {
  205.          goto done;
  206.          };
  207.    
  208.     mant2 >>= expdiff;
  209.     mant1 += mant2;
  210. done:
  211.     if (mant1 & (FLOAT64_HIDDEN_BIT_MASK << 7) ) {
  212.         ++exp1;
  213.         mant1 >>= 1;
  214.     };
  215.    
  216.     /* rounding - if first bit after mantisa is set then round up */
  217.     mant1 += (0x1 << 5);
  218.    
  219.     if (mant1 & (FLOAT64_HIDDEN_BIT_MASK << 7)) {
  220.         ++exp1;
  221.         mant1 >>= 1;
  222.     };
  223.    
  224.     a.parts.exp = exp1;
  225.     /*Clear hidden bit and shift */
  226.     a.parts.mantisa = ( (mant1 >> 6 ) & (~FLOAT64_HIDDEN_BIT_MASK));
  227.     return a;
  228. }
  229.  
  230.  
  231.