div.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Josef Cejka
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00035 #include <sftypes.h>
00036 #include <add.h>
00037 #include <div.h>
00038 #include <comparison.h>
00039 #include <mul.h>
00040 #include <common.h>
00041 
00042 float32 divFloat32(float32 a, float32 b) 
00043 {
00044         float32 result;
00045         int32_t aexp, bexp, cexp;
00046         uint64_t afrac, bfrac, cfrac;
00047         
00048         result.parts.sign = a.parts.sign ^ b.parts.sign;
00049         
00050         if (isFloat32NaN(a)) {
00051                 if (isFloat32SigNaN(a)) {
00052                         /*FIXME: SigNaN*/
00053                 }
00054                 /*NaN*/
00055                 return a;
00056         }
00057         
00058         if (isFloat32NaN(b)) {
00059                 if (isFloat32SigNaN(b)) {
00060                         /*FIXME: SigNaN*/
00061                 }
00062                 /*NaN*/
00063                 return b;
00064         }
00065         
00066         if (isFloat32Infinity(a)) {
00067                 if (isFloat32Infinity(b)) {
00068                         /*FIXME: inf / inf */
00069                         result.binary = FLOAT32_NAN;
00070                         return result;
00071                 }
00072                 /* inf / num */
00073                 result.parts.exp = a.parts.exp;
00074                 result.parts.fraction = a.parts.fraction;
00075                 return result;
00076         }
00077 
00078         if (isFloat32Infinity(b)) {
00079                 if (isFloat32Zero(a)) {
00080                         /* FIXME 0 / inf */
00081                         result.parts.exp = 0;
00082                         result.parts.fraction = 0;
00083                         return result;
00084                 }
00085                 /* FIXME: num / inf*/
00086                 result.parts.exp = 0;
00087                 result.parts.fraction = 0;
00088                 return result;
00089         }
00090         
00091         if (isFloat32Zero(b)) {
00092                 if (isFloat32Zero(a)) {
00093                         /*FIXME: 0 / 0*/
00094                         result.binary = FLOAT32_NAN;
00095                         return result;
00096                 }
00097                 /* FIXME: division by zero */
00098                 result.parts.exp = 0;
00099                 result.parts.fraction = 0;
00100                 return result;
00101         }
00102 
00103         
00104         afrac = a.parts.fraction;
00105         aexp = a.parts.exp;
00106         bfrac = b.parts.fraction;
00107         bexp = b.parts.exp;
00108         
00109         /* denormalized numbers */
00110         if (aexp == 0) {
00111                 if (afrac == 0) {
00112                 result.parts.exp = 0;
00113                 result.parts.fraction = 0;
00114                 return result;
00115                 }
00116                 /* normalize it*/
00117                 
00118                 afrac <<= 1;
00119                         /* afrac is nonzero => it must stop */  
00120                 while (! (afrac & FLOAT32_HIDDEN_BIT_MASK) ) {
00121                         afrac <<= 1;
00122                         aexp--;
00123                 }
00124         }
00125 
00126         if (bexp == 0) {
00127                 bfrac <<= 1;
00128                         /* bfrac is nonzero => it must stop */  
00129                 while (! (bfrac & FLOAT32_HIDDEN_BIT_MASK) ) {
00130                         bfrac <<= 1;
00131                         bexp--;
00132                 }
00133         }
00134 
00135         afrac = (afrac | FLOAT32_HIDDEN_BIT_MASK ) << (32 - FLOAT32_FRACTION_SIZE - 1 );
00136         bfrac = (bfrac | FLOAT32_HIDDEN_BIT_MASK ) << (32 - FLOAT32_FRACTION_SIZE );
00137 
00138         if ( bfrac <= (afrac << 1) ) {
00139                 afrac >>= 1;
00140                 aexp++;
00141         }
00142         
00143         cexp = aexp - bexp + FLOAT32_BIAS - 2;
00144         
00145         cfrac = (afrac << 32) / bfrac;
00146         if ((  cfrac & 0x3F ) == 0) { 
00147                 cfrac |= ( bfrac * cfrac != afrac << 32 );
00148         }
00149         
00150         /* pack and round */
00151         
00152         /* find first nonzero digit and shift result and detect possibly underflow */
00153         while ((cexp > 0) && (cfrac) && (!(cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7 )))) {
00154                 cexp--;
00155                 cfrac <<= 1;
00156                         /* TODO: fix underflow */
00157         };
00158         
00159         cfrac += (0x1 << 6); /* FIXME: 7 is not sure*/
00160         
00161         if (cfrac & (FLOAT32_HIDDEN_BIT_MASK << 7)) {
00162                 ++cexp;
00163                 cfrac >>= 1;
00164                 }       
00165 
00166         /* check overflow */
00167         if (cexp >= FLOAT32_MAX_EXPONENT ) {
00168                 /* FIXME: overflow, return infinity */
00169                 result.parts.exp = FLOAT32_MAX_EXPONENT;
00170                 result.parts.fraction = 0;
00171                 return result;
00172         }
00173 
00174         if (cexp < 0) {
00175                 /* FIXME: underflow */
00176                 result.parts.exp = 0;
00177                 if ((cexp + FLOAT32_FRACTION_SIZE) < 0) {
00178                         result.parts.fraction = 0;
00179                         return result;
00180                 }
00181                 cfrac >>= 1;
00182                 while (cexp < 0) {
00183                         cexp ++;
00184                         cfrac >>= 1;
00185                 }
00186                 
00187         } else {
00188                 result.parts.exp = (uint32_t)cexp;
00189         }
00190         
00191         result.parts.fraction = ((cfrac >> 6) & (~FLOAT32_HIDDEN_BIT_MASK)); 
00192         
00193         return result;  
00194 }
00195 
00196 float64 divFloat64(float64 a, float64 b) 
00197 {
00198         float64 result;
00199         int64_t aexp, bexp, cexp;
00200         uint64_t afrac, bfrac, cfrac; 
00201         uint64_t remlo, remhi;
00202         
00203         result.parts.sign = a.parts.sign ^ b.parts.sign;
00204         
00205         if (isFloat64NaN(a)) {
00206                 
00207                 if (isFloat64SigNaN(b)) {
00208                         /*FIXME: SigNaN*/
00209                         return b;
00210                 }
00211                 
00212                 if (isFloat64SigNaN(a)) {
00213                         /*FIXME: SigNaN*/
00214                 }
00215                 /*NaN*/
00216                 return a;
00217         }
00218         
00219         if (isFloat64NaN(b)) {
00220                 if (isFloat64SigNaN(b)) {
00221                         /*FIXME: SigNaN*/
00222                 }
00223                 /*NaN*/
00224                 return b;
00225         }
00226         
00227         if (isFloat64Infinity(a)) {
00228                 if (isFloat64Infinity(b) || isFloat64Zero(b)) {
00229                         /*FIXME: inf / inf */
00230                         result.binary = FLOAT64_NAN;
00231                         return result;
00232                 }
00233                 /* inf / num */
00234                 result.parts.exp = a.parts.exp;
00235                 result.parts.fraction = a.parts.fraction;
00236                 return result;
00237         }
00238 
00239         if (isFloat64Infinity(b)) {
00240                 if (isFloat64Zero(a)) {
00241                         /* FIXME 0 / inf */
00242                         result.parts.exp = 0;
00243                         result.parts.fraction = 0;
00244                         return result;
00245                 }
00246                 /* FIXME: num / inf*/
00247                 result.parts.exp = 0;
00248                 result.parts.fraction = 0;
00249                 return result;
00250         }
00251         
00252         if (isFloat64Zero(b)) {
00253                 if (isFloat64Zero(a)) {
00254                         /*FIXME: 0 / 0*/
00255                         result.binary = FLOAT64_NAN;
00256                         return result;
00257                 }
00258                 /* FIXME: division by zero */
00259                 result.parts.exp = 0;
00260                 result.parts.fraction = 0;
00261                 return result;
00262         }
00263 
00264         
00265         afrac = a.parts.fraction;
00266         aexp = a.parts.exp;
00267         bfrac = b.parts.fraction;
00268         bexp = b.parts.exp;
00269         
00270         /* denormalized numbers */
00271         if (aexp == 0) {
00272                 if (afrac == 0) {
00273                         result.parts.exp = 0;
00274                         result.parts.fraction = 0;
00275                         return result;
00276                 }
00277                 /* normalize it*/
00278                 
00279                 aexp++;
00280                         /* afrac is nonzero => it must stop */  
00281                 while (! (afrac & FLOAT64_HIDDEN_BIT_MASK) ) {
00282                         afrac <<= 1;
00283                         aexp--;
00284                 }
00285         }
00286 
00287         if (bexp == 0) {
00288                 bexp++;
00289                         /* bfrac is nonzero => it must stop */  
00290                 while (! (bfrac & FLOAT64_HIDDEN_BIT_MASK) ) {
00291                         bfrac <<= 1;
00292                         bexp--;
00293                 }
00294         }
00295 
00296         afrac = (afrac | FLOAT64_HIDDEN_BIT_MASK ) << (64 - FLOAT64_FRACTION_SIZE - 2 );
00297         bfrac = (bfrac | FLOAT64_HIDDEN_BIT_MASK ) << (64 - FLOAT64_FRACTION_SIZE - 1);
00298 
00299         if ( bfrac <= (afrac << 1) ) {
00300                 afrac >>= 1;
00301                 aexp++;
00302         }
00303         
00304         cexp = aexp - bexp + FLOAT64_BIAS - 2; 
00305         
00306         cfrac = divFloat64estim(afrac, bfrac);
00307         
00308         if ((  cfrac & 0x1FF ) <= 2) { /*FIXME:?? */
00309                 mul64integers( bfrac, cfrac, &remlo, &remhi);
00310                 /* (__u128)afrac << 64 - ( ((__u128)remhi<<64) + (__u128)remlo )*/      
00311                 remhi = afrac - remhi - ( remlo > 0);
00312                 remlo = - remlo;
00313                 
00314                 while ((int64_t) remhi < 0) {
00315                         cfrac--;
00316                         remlo += bfrac;
00317                         remhi += ( remlo < bfrac );
00318                 }
00319                 cfrac |= ( remlo != 0 );
00320         }
00321         
00322         /* round and shift */
00323         result = finishFloat64(cexp, cfrac, result.parts.sign);
00324         return result;
00325 
00326 }
00327 
00328 uint64_t divFloat64estim(uint64_t a, uint64_t b)
00329 {
00330         uint64_t bhi;
00331         uint64_t remhi, remlo;
00332         uint64_t result;
00333         
00334         if ( b <= a ) {
00335                 return 0xFFFFFFFFFFFFFFFFull;
00336         }
00337         
00338         bhi = b >> 32;
00339         result = ((bhi << 32) <= a) ?( 0xFFFFFFFFull << 32) : ( a / bhi) << 32;
00340         mul64integers(b, result, &remlo, &remhi);
00341         
00342         remhi = a - remhi - (remlo > 0);
00343         remlo = - remlo;
00344 
00345         b <<= 32;
00346         while ( (int64_t) remhi < 0 ) {
00347                         result -= 0x1ll << 32;  
00348                         remlo += b;
00349                         remhi += bhi + ( remlo < b );
00350                 }
00351         remhi = (remhi << 32) | (remlo >> 32);
00352         if (( bhi << 32) <= remhi) {
00353                 result |= 0xFFFFFFFF;
00354         } else {
00355                 result |= remhi / bhi;
00356         }
00357         
00358         
00359         return result;
00360 }
00361 

Generated on Thu Jun 2 07:45:48 2011 for HelenOS/USB by  doxygen 1.4.7