<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>addition_scs.c Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.2.15 --> <center> <a class="qindex" href="index.html">Main Page</a> <a class="qindex" href="annotated.html">Data Structures</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Data Fields</a> <a class="qindex" href="globals.html">Globals</a> </center> <hr><h1>addition_scs.c</h1><a href="addition__scs_8c.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 <font class="comment">/** Functions for SCS addition and subtraction </font> 00002 <font class="comment"></font> 00003 <font class="comment">@file addition_scs.c</font> 00004 <font class="comment"></font> 00005 <font class="comment">@author Defour David David.Defour@ens-lyon.fr</font> 00006 <font class="comment">@author Florent de Dinechin Florent.de.Dinechin@ens-lyon.fr </font> 00007 <font class="comment"> </font> 00008 <font class="comment">This file is part of the SCS library.</font> 00009 <font class="comment"></font> 00010 <font class="comment">Many functions come in two versions, selected by a @#if.</font> 00011 <font class="comment"></font> 00012 <font class="comment">The reason is that we designed scslib library for internal use with</font> 00013 <font class="comment">SCS_NB_WORDS==8, so we provide a version with manual optimizations for</font> 00014 <font class="comment">this case.</font> 00015 <font class="comment"></font> 00016 <font class="comment">These optimisations include loop unrolling, and sometimes replacing</font> 00017 <font class="comment">temporary arrays of size 8 with 8 variables, which is more efficient</font> 00018 <font class="comment">on all modern processors with many (renaming) registers.</font> 00019 <font class="comment"></font> 00020 <font class="comment">Using gcc3.2 with the most aggressive optimization options for this</font> 00021 <font class="comment">purpose (-funroll-loops -foptimize-register-move -frerun-loop-opt</font> 00022 <font class="comment">-frerun-cse-after-loop) is still much slower. At some point in the</font> 00023 <font class="comment">future, gcc should catch up with unrolling since our loops are so</font> 00024 <font class="comment">simple, however the replacement of small arrays with variables is</font> 00025 <font class="comment">not something we are aware of in the literature about compiler</font> 00026 <font class="comment">optimization.</font> 00027 <font class="comment">*/</font> 00028 00029 <font class="comment">/*</font> 00030 <font class="comment">Copyright (C) 2002 David Defour and Florent de Dinechin</font> 00031 <font class="comment"></font> 00032 <font class="comment"> This library is free software; you can redistribute it and/or</font> 00033 <font class="comment"> modify it under the terms of the GNU Lesser General Public</font> 00034 <font class="comment"> License as published by the Free Software Foundation; either</font> 00035 <font class="comment"> version 2.1 of the License, or (at your option) any later version.</font> 00036 <font class="comment"></font> 00037 <font class="comment"> This library is distributed in the hope that it will be useful,</font> 00038 <font class="comment"> but WITHOUT ANY WARRANTY; without even the implied warranty of</font> 00039 <font class="comment"> MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU</font> 00040 <font class="comment"> Lesser General Public License for more details.</font> 00041 <font class="comment"></font> 00042 <font class="comment"> You should have received a copy of the GNU Lesser General Public</font> 00043 <font class="comment"> License along with this library; if not, write to the Free Software</font> 00044 <font class="comment"> Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA</font> 00045 <font class="comment"></font> 00046 <font class="comment"> */</font> 00047 00048 <font class="preprocessor">#include "<a class="code" href="scs_8h.html">scs.h</a>"</font> 00049 <font class="preprocessor">#include "<a class="code" href="scs__private_8h.html">scs_private.h</a>"</font> 00050 <font class="comment"></font> 00051 <font class="comment">/**</font> 00052 <font class="comment">This function copies a result into another. There is an unrolled</font> 00053 <font class="comment">version for the case SCS_NB_WORDS==8.</font> 00054 <font class="comment">*/</font> <a name="l00055"></a><a class="code" href="addition__scs_8c.html#a0">00055</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x){ 00056 <font class="comment">/* unsigned int i;*/</font> 00057 00058 <font class="preprocessor">#if (SCS_NB_WORDS==8)</font> 00059 <font class="preprocessor"></font> R_HW[0] = X_HW[0]; R_HW[1] = X_HW[1]; 00060 R_HW[2] = X_HW[2]; R_HW[3] = X_HW[3]; 00061 R_HW[4] = X_HW[4]; R_HW[5] = X_HW[5]; 00062 R_HW[6] = X_HW[6]; R_HW[7] = X_HW[7]; 00063 <font class="preprocessor">#else</font> 00064 <font class="preprocessor"></font> <font class="keywordflow">for</font>(i=0; i<SCS_NB_WORDS; i++) 00065 R_HW[i] = X_HW[i]; 00066 <font class="preprocessor">#endif</font> 00067 <font class="preprocessor"></font> R_EXP = X_EXP; 00068 R_IND = X_IND; 00069 R_SGN = X_SGN; 00070 } 00071 00072 <font class="comment"></font> 00073 <font class="comment">/** renormalize a SCS number. </font> 00074 <font class="comment"></font> 00075 <font class="comment">This function removes the carry from each digit, and also shifts the</font> 00076 <font class="comment">digits in case of a cancellation (so that if result != 0 then its</font> 00077 <font class="comment">first digit is non-zero)</font> 00078 <font class="comment"> </font> 00079 <font class="comment"> @warning THIS FUNCTION HAS NEVER BEEN PROPERLY TESTED and is</font> 00080 <font class="comment"> currently unused in the library: instead, specific renormalisation</font> 00081 <font class="comment"> steps are fused within the code of the operations which require it.</font> 00082 <font class="comment"> */</font> 00083 <a name="l00084"></a><a class="code" href="addition__scs_8c.html#a1">00084</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a1">scs_renorm</a>(<a class="code" href="structscs.html">scs_ptr</a> result){ 00085 <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> c; 00086 <font class="keywordtype">int</font> i, j, k; 00087 00088 <font class="comment">/*</font> 00089 <font class="comment"> * Carry propagate</font> 00090 <font class="comment"> */</font> 00091 <font class="keywordflow">for</font>(i=SCS_NB_WORDS-1; i>0; i--){ 00092 c = R_HW[i] & ~SCS_MASK_RADIX; 00093 R_HW[i-1] += c >> SCS_NB_BITS; 00094 R_HW[i] = R_HW[i] & SCS_MASK_RADIX; 00095 } 00096 00097 <font class="keywordflow">if</font> (R_HW[0] >= SCS_RADIX){ 00098 <font class="comment">/* Carry out! Need to shift digits */</font> 00099 c = R_HW[0] & ~SCS_MASK_RADIX; 00100 c = c >> SCS_NB_BITS; 00101 <font class="keywordflow">for</font>(i=SCS_NB_WORDS-1; i>1; i--) 00102 R_HW[i] = R_HW[i-1]; 00103 00104 R_HW[1] = R_HW[0] & SCS_MASK_RADIX; 00105 R_HW[0] = c; 00106 R_IND += 1; 00107 00108 }<font class="keywordflow">else</font>{ 00109 <font class="comment">/* Was there a cancellation ? */</font> 00110 <font class="keywordflow">if</font> (R_HW[0] == 0){ 00111 00112 k = 1; 00113 <font class="keywordflow">while</font> ((R_HW[k] == 0) && (k <= SCS_NB_WORDS)) 00114 k++; 00115 00116 R_IND -= k; 00117 00118 <font class="keywordflow">for</font>(j=k, i=0; j<SCS_NB_WORDS; j++, i++) 00119 R_HW[i] = R_HW[j]; 00120 00121 <font class="keywordflow">for</font>( ; i<SCS_NB_WORDS; i++) 00122 R_HW[i] = 0; 00123 00124 } 00125 } 00126 } 00127 00128 00129 <font class="comment"></font> 00130 <font class="comment">/** Renormalization without cancellation check.</font> 00131 <font class="comment"></font> 00132 <font class="comment"> This renormalization step is especially designed for the addition of</font> 00133 <font class="comment"> several numbers with the same sign. In this case, you know that there</font> 00134 <font class="comment"> has been no cancellation, which allows simpler renormalisation.</font> 00135 <font class="comment">*/</font> 00136 <a name="l00137"></a><a class="code" href="addition__scs_8c.html#a2">00137</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a2">scs_renorm_no_cancel_check</a>(<a class="code" href="structscs.html">scs_ptr</a> result){ 00138 <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> carry, c0; 00139 <font class="comment">/* int i;*/</font> 00140 00141 <font class="comment">/* Carry propagate */</font> 00142 <font class="preprocessor">#if (SCS_NB_WORDS==8)</font> 00143 <font class="preprocessor"></font> carry = R_HW[7] >> SCS_NB_BITS; 00144 R_HW[6] += carry; R_HW[7] = R_HW[7] & SCS_MASK_RADIX; 00145 carry = R_HW[6] >> SCS_NB_BITS; 00146 R_HW[5] += carry; R_HW[6] = R_HW[6] & SCS_MASK_RADIX; 00147 carry = R_HW[5] >> SCS_NB_BITS; 00148 R_HW[4] += carry; R_HW[5] = R_HW[5] & SCS_MASK_RADIX; 00149 carry = R_HW[4] >> SCS_NB_BITS; 00150 R_HW[3] += carry; R_HW[4] = R_HW[4] & SCS_MASK_RADIX; 00151 carry = R_HW[3] >> SCS_NB_BITS; 00152 R_HW[2] += carry; R_HW[3] = R_HW[3] & SCS_MASK_RADIX; 00153 carry = R_HW[2] >> SCS_NB_BITS; 00154 R_HW[1] += carry; R_HW[2] = R_HW[2] & SCS_MASK_RADIX; 00155 carry = R_HW[1] >> SCS_NB_BITS; 00156 R_HW[0] += carry; R_HW[1] = R_HW[1] & SCS_MASK_RADIX; 00157 <font class="preprocessor">#else</font> 00158 <font class="preprocessor"></font> <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1);i>0;i--){ 00159 carry = R_HW[i] >> SCS_NB_BITS; 00160 R_HW[i-1] += carry; 00161 R_HW[i] = R_HW[i] & SCS_MASK_RADIX; 00162 } 00163 <font class="preprocessor">#endif</font> 00164 <font class="preprocessor"></font> 00165 <font class="keywordflow">if</font> (R_HW[0] >= SCS_RADIX){ 00166 <font class="comment">/* Carry out ! Need to shift digits */</font> 00167 c0 = R_HW[0] >> SCS_NB_BITS; 00168 00169 <font class="preprocessor">#if (SCS_NB_WORDS==8)</font> 00170 <font class="preprocessor"></font> R_HW[7] = R_HW[6]; R_HW[6] = R_HW[5]; 00171 R_HW[5] = R_HW[4]; R_HW[4] = R_HW[3]; 00172 R_HW[3] = R_HW[2]; R_HW[2] = R_HW[1]; 00173 <font class="preprocessor">#else</font> 00174 <font class="preprocessor"></font> <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1); i>1; i--) 00175 R_HW[i] = R_HW[i-1]; 00176 <font class="preprocessor">#endif </font> 00177 <font class="preprocessor"></font> R_HW[1] = R_HW[0] & SCS_MASK_RADIX; 00178 R_HW[0] = c0; 00179 R_IND += 1; 00180 } 00181 <font class="keywordflow">return</font>; 00182 } 00183 00184 00185 00186 00187 <font class="comment">/* addition without renormalisation.</font> 00188 <font class="comment"></font> 00189 <font class="comment"></font> 00190 <font class="comment"> Add two scs number x and y, the result is put into "result".</font> 00191 <font class="comment"> Assumes x.sign == y.sign x.index > y.index. </font> 00192 <font class="comment"></font> 00193 <font class="comment"> The result is not normalized.</font> 00194 <font class="comment"> */</font> 00195 00196 <font class="keywordtype">void</font> do_add_no_renorm(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y){ 00197 <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> RES[SCS_NB_WORDS]; 00198 <font class="keywordtype">unsigned</font> <font class="keywordtype">int</font> i, j, Diff; 00199 00200 <font class="keywordflow">if</font> (x-><a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0){<a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, y); <font class="keywordflow">return</font>; } 00201 <font class="keywordflow">if</font> (y-><a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0){<a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>; } 00202 00203 <font class="keywordflow">for</font> (i=0; i<SCS_NB_WORDS; i++) 00204 RES[i] = X_HW[i]; 00205 00206 Diff = X_IND - Y_IND; 00207 R_EXP = X_EXP + Y_EXP - 1; 00208 R_IND = X_IND; 00209 R_SGN = X_SGN; 00210 00211 <font class="keywordflow">for</font> (i=Diff, j=0; i<SCS_NB_WORDS; i++, j++) 00212 RES[i] += Y_HW[j]; 00213 00214 <font class="keywordflow">for</font> (i=0; i<SCS_NB_WORDS; i++) 00215 R_HW[i] = RES[i]; 00216 00217 <font class="keywordflow">return</font>; 00218 } 00219 00220 00221 <font class="comment">/*</font> 00222 <font class="comment"> * Addition without renormalization. Assumes that x.sign == y.sign.</font> 00223 <font class="comment"> */</font> <a name="l00224"></a><a class="code" href="addition__scs_8c.html#a4">00224</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a4">scs_add_no_renorm</a>(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y) 00225 { 00226 <font class="keywordflow">if</font> (X_IND >= Y_IND) 00227 do_add_no_renorm(result,x,y); 00228 <font class="keywordflow">else</font> 00229 do_add_no_renorm(result,y,x); 00230 <font class="keywordflow">return</font>; 00231 } 00232 00233 00234 00235 00236 00237 00238 00239 00240 00241 00242 00243 00244 00245 00246 00247 00248 <font class="comment">/* The function that does the work in case of an addition</font> 00249 <font class="comment"></font> 00250 <font class="comment"> do_add is the function that does the addition of two SCS numbers,</font> 00251 <font class="comment"> assuming that x.sign == y.sign, X_IND > Y_IND, x and y both</font> 00252 <font class="comment"> non-zero. </font> 00253 <font class="comment"> */</font> 00254 00255 <font class="keywordtype">void</font> <font class="keyword">inline</font> do_add(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y) 00256 { 00257 <font class="preprocessor">#if (SCS_NB_WORDS==8) </font><font class="comment">/* in this case we unroll all the loops */</font> 00258 <font class="keywordtype">int</font> carry, Diff; 00259 <font class="keywordtype">int</font> r0,r1,r2,r3,r4,r5,r6,r7; 00260 00261 Diff = X_IND - Y_IND; 00262 R_EXP = X_EXP + Y_EXP - 1; 00263 R_IND = X_IND; 00264 R_SGN = X_SGN; 00265 00266 <font class="keywordflow">switch</font> (Diff){ 00267 <font class="keywordflow">case</font> 0: 00268 r0 = X_HW[0] + Y_HW[0]; r1 = X_HW[1] + Y_HW[1]; 00269 r2 = X_HW[2] + Y_HW[2]; r3 = X_HW[3] + Y_HW[3]; 00270 r4 = X_HW[4] + Y_HW[4]; r5 = X_HW[5] + Y_HW[5]; 00271 r6 = X_HW[6] + Y_HW[6]; r7 = X_HW[7] + Y_HW[7]; <font class="keywordflow">break</font>; 00272 <font class="keywordflow">case</font> 1: 00273 r0 = X_HW[0]; r1 = X_HW[1] + Y_HW[0]; 00274 r2 = X_HW[2] + Y_HW[1]; r3 = X_HW[3] + Y_HW[2]; 00275 r4 = X_HW[4] + Y_HW[3]; r5 = X_HW[5] + Y_HW[4]; 00276 r6 = X_HW[6] + Y_HW[5]; r7 = X_HW[7] + Y_HW[6]; <font class="keywordflow">break</font>; 00277 <font class="keywordflow">case</font> 2: 00278 r0 = X_HW[0]; r1 = X_HW[1]; 00279 r2 = X_HW[2] + Y_HW[0]; r3 = X_HW[3] + Y_HW[1]; 00280 r4 = X_HW[4] + Y_HW[2]; r5 = X_HW[5] + Y_HW[3]; 00281 r6 = X_HW[6] + Y_HW[4]; r7 = X_HW[7] + Y_HW[5]; <font class="keywordflow">break</font>; 00282 <font class="keywordflow">case</font> 3: 00283 r0 = X_HW[0]; r1 = X_HW[1]; 00284 r2 = X_HW[2]; r3 = X_HW[3] + Y_HW[0]; 00285 r4 = X_HW[4] + Y_HW[1]; r5 = X_HW[5] + Y_HW[2]; 00286 r6 = X_HW[6] + Y_HW[3]; r7 = X_HW[7] + Y_HW[4]; <font class="keywordflow">break</font>; 00287 <font class="keywordflow">case</font> 4: 00288 r0 = X_HW[0]; r1 = X_HW[1]; 00289 r2 = X_HW[2]; r3 = X_HW[3]; 00290 r4 = X_HW[4] + Y_HW[0]; r5 = X_HW[5] + Y_HW[1]; 00291 r6 = X_HW[6] + Y_HW[2]; r7 = X_HW[7] + Y_HW[3]; <font class="keywordflow">break</font>; 00292 <font class="keywordflow">case</font> 5: 00293 r0 = X_HW[0]; r1 = X_HW[1]; 00294 r2 = X_HW[2]; r3 = X_HW[3]; 00295 r4 = X_HW[4]; r5 = X_HW[5] + Y_HW[0]; 00296 r6 = X_HW[6] + Y_HW[1]; r7 = X_HW[7] + Y_HW[2]; <font class="keywordflow">break</font>; 00297 <font class="keywordflow">case</font> 6: 00298 r0 = X_HW[0]; r1 = X_HW[1]; 00299 r2 = X_HW[2]; r3 = X_HW[3]; 00300 r4 = X_HW[4]; r5 = X_HW[5]; 00301 r6 = X_HW[6] + Y_HW[0]; r7 = X_HW[7] + Y_HW[1]; <font class="keywordflow">break</font>; 00302 <font class="keywordflow">case</font> 7: 00303 r0 = X_HW[0]; r1 = X_HW[1]; 00304 r2 = X_HW[2]; r3 = X_HW[3]; 00305 r4 = X_HW[4]; r5 = X_HW[5]; 00306 r6 = X_HW[6]; r7 = X_HW[7] + Y_HW[0]; <font class="keywordflow">break</font>; 00307 <font class="keywordflow">default</font>: 00308 <font class="comment">/* Diff >= 8*/</font> 00309 R_HW[0] = X_HW[0]; R_HW[1] = X_HW[1]; 00310 R_HW[2] = X_HW[2]; R_HW[3] = X_HW[3]; 00311 R_HW[4] = X_HW[4]; R_HW[5] = X_HW[5]; 00312 R_HW[6] = X_HW[6]; R_HW[7] = X_HW[7]; <font class="keywordflow">return</font>; 00313 } 00314 00315 00316 <font class="comment">/* Carry propagation */</font> 00317 00318 carry = r7 >> SCS_NB_BITS; r6 += carry; r7 = r7 & SCS_MASK_RADIX; 00319 carry = r6 >> SCS_NB_BITS; r5 += carry; r6 = r6 & SCS_MASK_RADIX; 00320 carry = r5 >> SCS_NB_BITS; r4 += carry; r5 = r5 & SCS_MASK_RADIX; 00321 carry = r4 >> SCS_NB_BITS; r3 += carry; r4 = r4 & SCS_MASK_RADIX; 00322 carry = r3 >> SCS_NB_BITS; r2 += carry; r3 = r3 & SCS_MASK_RADIX; 00323 carry = r2 >> SCS_NB_BITS; r1 += carry; r2 = r2 & SCS_MASK_RADIX; 00324 carry = r1 >> SCS_NB_BITS; r0 += carry; r1 = r1 & SCS_MASK_RADIX; 00325 carry = r0 >> SCS_NB_BITS; 00326 00327 <font class="keywordflow">if</font> (carry){ 00328 R_HW[7] = r6; R_HW[6] = r5; R_HW[5] = r4; R_HW[4] = r3; 00329 R_HW[3] = r2; R_HW[2] = r1; R_HW[1] = r0 & SCS_MASK_RADIX; 00330 R_HW[0] = 1 ; 00331 R_IND += 1; 00332 } 00333 <font class="keywordflow">else</font> { 00334 R_HW[0] = r0; R_HW[1] = r1; R_HW[2] = r2; R_HW[3] = r3; 00335 R_HW[4] = r4; R_HW[5] = r5; R_HW[6] = r6; R_HW[7] = r7; 00336 } 00337 <font class="keywordflow">return</font>; 00338 00339 <font class="preprocessor">#else </font><font class="comment">/* #if SCS_NB_WORDS==8*/</font> 00340 00341 <font class="comment">/* This generic version is still written in such a way that</font> 00342 <font class="comment"> it is unrollable at compile time</font> 00343 <font class="comment">*/</font> 00344 <font class="keywordtype">int</font> i,j, s, carry, Diff; 00345 <font class="keywordtype">int</font> res[SCS_NB_WORDS]; 00346 00347 Diff = X_IND - Y_IND; 00348 R_EXP = X_EXP + Y_EXP - 1; 00349 R_IND = X_IND; 00350 R_SGN = X_SGN; 00351 00352 <font class="comment">/* The easy case */</font> 00353 <font class="keywordflow">if</font>(Diff >= SCS_NB_WORDS){ 00354 <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>; 00355 } 00356 00357 <font class="comment">/* 0 <= Diff <= (SCS_NB_WORDS-1) */</font> 00358 00359 carry=0; 00360 <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1), j=((SCS_NB_WORDS-1)-Diff); i>=0 ; i--,j--){ 00361 <font class="keywordflow">if</font> (j>=0) 00362 s = X_HW[i] + Y_HW[j] + carry; 00363 <font class="keywordflow">else</font> 00364 s = X_HW[i] + carry; 00365 carry = s >> SCS_NB_BITS; 00366 res[i] = s & SCS_MASK_RADIX; 00367 } 00368 00369 <font class="keywordflow">if</font> (carry){ 00370 <font class="comment">/* Carry out ! Need to shift digits */</font> 00371 <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1); i>=1; i--) 00372 R_HW[i] = res[i-1]; 00373 00374 R_HW[0] = 1 ; 00375 R_IND += 1; 00376 } 00377 <font class="keywordflow">else</font> { 00378 <font class="keywordflow">for</font>(i=0; i<SCS_NB_WORDS; i++) 00379 R_HW[i] = res[i]; 00380 } 00381 00382 <font class="keywordflow">return</font>; 00383 <font class="preprocessor">#endif </font><font class="comment">/* #if SCS_NB_WORDS==8*/</font> 00384 00385 } <font class="comment">/* do_add*/</font> 00386 00387 00388 00389 00390 00391 00392 00393 00394 <font class="comment">/*</font> 00395 <font class="comment"> * Compare only the mantissa of x and y without the index or sign field</font> 00396 <font class="comment"> * Return : </font> 00397 <font class="comment"> * - 1 if x > y</font> 00398 <font class="comment"> * - (-1) if x < y</font> 00399 <font class="comment"> * - (0) if x = y</font> 00400 <font class="comment"> */</font> 00401 00402 <font class="keywordtype">int</font> <font class="keyword">inline</font> scs_cmp_mant(<a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y){ 00403 <font class="keywordtype">int</font> i; 00404 <font class="comment">/* Tried to unroll this loop, it doesn't work */</font> 00405 <font class="keywordflow">for</font>(i=0; i< SCS_NB_WORDS; i++){ 00406 <font class="keywordflow">if</font> (X_HW[i] == Y_HW[i]) <font class="keywordflow">continue</font>; 00407 <font class="keywordflow">else</font> <font class="keywordflow">if</font> (X_HW[i] > Y_HW[i]) <font class="keywordflow">return</font> 1; 00408 <font class="keywordflow">else</font> <font class="keywordflow">return</font> -1;} 00409 <font class="keywordflow">return</font> 0; 00410 } 00411 00412 00413 00414 <font class="comment">/*</font><font class="comment">/////////////////////////////////////////////////////////////////</font> 00415 <font class="comment"></font><font class="comment">/////////////////////// SUBTRACTION //////////////////////////////</font> 00416 <font class="comment"></font><font class="comment">//////////////////////////////////////////////////////////////////</font> 00417 <font class="comment"></font>// This procedure assumes : 00418 // - X_IND >= Y_IND 00419 // - X_SIGN != Y_SIGN 00420 // neither x or y is zero 00421 // and result = x - y 00422 */ 00423 00424 00425 <font class="keywordtype">void</font> <font class="keyword">inline</font> do_sub(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y){ 00426 <font class="keywordtype">int</font> s, carry; 00427 <font class="keywordtype">int</font> Diff, i, j, cp; 00428 <font class="keywordtype">int</font> res[SCS_NB_WORDS]; 00429 00430 R_EXP = X_EXP + Y_EXP - 1; 00431 Diff = X_IND - Y_IND; 00432 R_IND = X_IND; 00433 00434 <font class="comment">/* The easy case */</font> 00435 <font class="keywordflow">if</font>(Diff >= SCS_NB_WORDS){ 00436 <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>; 00437 } 00438 00439 <font class="keywordflow">else</font> { 00440 <font class="comment">/* 0 <= Diff <= (SCS_NB_WORDS-1) */</font> 00441 carry = 0; 00442 <font class="keywordflow">if</font>(Diff==0) { 00443 cp = scs_cmp_mant(x, y); 00444 00445 <font class="keywordflow">if</font> (cp == 0) { 00446 <font class="comment">/* Yet another easy case: result = 0 */</font> 00447 <a class="code" href="zero__scs_8c.html#a0">scs_zero</a>(result); 00448 <font class="keywordflow">return</font>; 00449 } 00450 <font class="keywordflow">else</font> { <font class="comment">/* cp <> 0 */</font> 00451 <font class="keywordflow">if</font> (cp > 0){ 00452 <font class="comment">/* x > y */</font> 00453 00454 R_SGN = X_SGN; 00455 <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1); i>=0 ;i--){ 00456 s = X_HW[i] - Y_HW[i] - carry; 00457 carry = (s&SCS_RADIX)>>SCS_NB_BITS; 00458 res[i] = (s&SCS_RADIX) + s; 00459 } 00460 } 00461 <font class="keywordflow">else</font> { <font class="comment">/* cp < 0 */</font> 00462 <font class="comment">/* x < y (change of sign) */</font> 00463 00464 R_SGN = - X_SGN; 00465 <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1); i>=0 ;i--){ 00466 s = - X_HW[i] + Y_HW[i] - carry; 00467 carry = (s&SCS_RADIX)>>SCS_NB_BITS; 00468 res[i] = (s&SCS_RADIX) + s; 00469 } 00470 } 00471 } 00472 } 00473 <font class="keywordflow">else</font> { 00474 <font class="comment">/* 1<=Diff<(SCS_NB_WORDS-1) Digits of x and y overlap but the</font> 00475 <font class="comment"> * sign will be that of x */</font> 00476 00477 R_SGN = X_SGN; 00478 <font class="keywordflow">for</font>(i=(SCS_NB_WORDS-1), j=((SCS_NB_WORDS-1)-Diff); i>=0 ;i--,j--){ 00479 <font class="keywordflow">if</font>(j>=0) 00480 s = X_HW[i] - Y_HW[j] - carry; 00481 <font class="keywordflow">else</font> 00482 s = X_HW[i] - carry; 00483 carry = (s&SCS_RADIX)>>SCS_NB_BITS; 00484 res[i] = (s&SCS_RADIX) + s; 00485 } 00486 } 00487 <font class="comment">/* check for cancellations */</font> 00488 i=0; 00489 <font class="keywordflow">while</font> ((res[i]==0) && (i < SCS_NB_WORDS)) i++; 00490 00491 <font class="keywordflow">if</font>(i>0) { <font class="comment">/* cancellation, shift result*/</font> 00492 R_IND -= i; 00493 <font class="keywordflow">for</font>(j=0; i<SCS_NB_WORDS; i++,j++) R_HW[j] = res[i]; 00494 <font class="keywordflow">for</font>( ; j<SCS_NB_WORDS; j++) R_HW[j] = 0; 00495 } 00496 <font class="keywordflow">else</font> { 00497 <font class="keywordflow">for</font>(i=0; i<SCS_NB_WORDS; i++) 00498 R_HW[i] = res[i]; 00499 } 00500 } 00501 <font class="keywordflow">return</font>; 00502 } 00503 00504 00505 00506 00507 00508 00509 00510 <font class="comment"></font> 00511 <font class="comment">/** SCS addition (result is a normalised SCS number).</font> 00512 <font class="comment"></font> 00513 <font class="comment"> */</font> <a name="l00514"></a><a class="code" href="addition__scs_8c.html#a8">00514</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a8">scs_add</a>(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y) 00515 { 00516 00517 <font class="keywordflow">if</font> (x-><a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0){<a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, y); <font class="keywordflow">return</font>; } 00518 <font class="keywordflow">if</font> (y-><a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0){<a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>; } 00519 00520 <font class="keywordflow">if</font> (X_SGN == Y_SGN){ 00521 <font class="keywordflow">if</font>(X_IND >= Y_IND) 00522 do_add(result,x,y); 00523 <font class="keywordflow">else</font> 00524 do_add(result,y,x); 00525 }<font class="keywordflow">else</font> { 00526 <font class="keywordflow">if</font>(X_IND>=Y_IND){ 00527 do_sub(result,x,y); 00528 }<font class="keywordflow">else</font> { 00529 do_sub(result,y,x); 00530 } 00531 } <font class="keywordflow">return</font>; 00532 } 00533 <font class="comment"></font> 00534 <font class="comment">/** SCS subtraction (result is a normalised SCS number).</font> 00535 <font class="comment"></font> 00536 <font class="comment"> The arguments x, y and result may point to the same memory</font> 00537 <font class="comment"> location. </font> 00538 <font class="comment"> */</font> <a name="l00539"></a><a class="code" href="addition__scs_8c.html#a9">00539</a> <font class="keywordtype">void</font> <font class="keyword">inline</font> <a class="code" href="addition__scs_8c.html#a9">scs_sub</a>(<a class="code" href="structscs.html">scs_ptr</a> result, <a class="code" href="structscs.html">scs_ptr</a> x, <a class="code" href="structscs.html">scs_ptr</a> y) 00540 { 00541 <font class="keywordflow">if</font> (x-><a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0) 00542 { <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, y); R_SGN = -R_SGN; <font class="keywordflow">return</font>; } 00543 <font class="keywordflow">if</font> (y-><a class="code" href="structscs.html#m1">exception</a>.i[HI_ENDIAN]==0) 00544 { <a class="code" href="addition__scs_8c.html#a0">scs_set</a>(result, x); <font class="keywordflow">return</font>; } 00545 00546 <font class="keywordflow">if</font> (X_SGN == Y_SGN) { 00547 <font class="comment">/* Same sign, so it's a sub */</font> 00548 <font class="keywordflow">if</font>(X_IND>=Y_IND) 00549 do_sub(result,x,y); 00550 <font class="keywordflow">else</font>{ 00551 do_sub(result,y,x); 00552 R_SGN = -R_SGN; 00553 } 00554 }<font class="keywordflow">else</font> { 00555 <font class="keywordflow">if</font>(X_IND>=Y_IND) 00556 do_add(result,x,y); 00557 <font class="keywordflow">else</font>{ 00558 do_add(result,y,x); 00559 R_SGN = -R_SGN; 00560 } 00561 } 00562 <font class="keywordflow">return</font>; 00563 } 00564 00565 </pre></div><hr><address align="right"><small>Generated on Tue Jun 17 10:15:51 2003 for SCSLib by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.15 </small></address> </body> </html>