File indexing completed on 2024-05-12 05:55:14
0001 /* floatlogic.c: logic functions, based on floatnum. */ 0002 /* 0003 Copyright (C) 2007, 2008 Wolf Lammen. 0004 0005 This program is free software; you can redistribute it and/or modify 0006 it under the terms of the GNU General Public License as published by 0007 the Free Software Foundation; either version 2 of the License , or 0008 (at your option) any later version. 0009 0010 This program is distributed in the hope that it will be useful, 0011 but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 GNU General Public License for more details. 0014 0015 You should have received a copy of the GNU General Public License 0016 along with this program; see the file COPYING. If not, write to: 0017 0018 The Free Software Foundation, Inc. 0019 59 Temple Place, Suite 330 0020 Boston, MA 02111-1307 USA. 0021 0022 0023 You may contact the author by: 0024 e-mail: ookami1 <at> gmx <dot> de 0025 mail: Wolf Lammen 0026 Oertzweg 45 0027 22307 Hamburg 0028 Germany 0029 0030 *************************************************************************/ 0031 0032 #include "floatlogic.h" 0033 #include "floatconst.h" 0034 0035 #define MAXIDX ((LOGICRANGE-1) / BITS_IN_UNSIGNED) 0036 #define SIGNBIT (LOGICRANGE - 1 - MAXIDX * BITS_IN_UNSIGNED) 0037 0038 static void 0039 _zeroextend( 0040 t_longint* longint) 0041 { 0042 int idx; 0043 0044 idx = longint->length - 1; 0045 for (; ++idx <= (int)MAXIDX;) 0046 longint->value[idx] = 0; 0047 } 0048 0049 signed char 0050 _signof( 0051 t_longint* longint) 0052 { 0053 return (longint->value[MAXIDX] & (1 << SIGNBIT)) != 0? -1:1; 0054 } 0055 0056 static char 0057 _signextend( 0058 t_longint* longint) 0059 { 0060 unsigned mask; 0061 signed char sign; 0062 0063 sign = _signof(longint); 0064 mask = (unsigned)(~0) << SIGNBIT; 0065 if (sign < 0) 0066 longint->value[MAXIDX] |= mask; 0067 else 0068 longint->value[MAXIDX] &= ~mask; 0069 return sign; 0070 } 0071 0072 static void 0073 _neg( 0074 t_longint* longint) 0075 { 0076 int idx = -1; 0077 const int maxidx = MAXIDX; 0078 while (++idx <= maxidx && longint->value[idx] == 0); 0079 if (idx <= maxidx) 0080 longint->value[idx] = - longint->value[idx]; 0081 while (++idx <= maxidx) 0082 longint->value[idx] = ~longint->value[idx]; 0083 } 0084 0085 char 0086 _floatnum2logic( 0087 t_longint* longint, 0088 cfloatnum x) 0089 { 0090 floatstruct tmp; 0091 int digits; 0092 0093 digits = float_getexponent(x)+1; 0094 if (float_iszero(x) || digits <= 0) 0095 { 0096 longint->length = 1; 0097 longint->value[0] = 0; 0098 } 0099 else 0100 { 0101 if (digits > MATHPRECISION) 0102 return 0; 0103 0104 float_create(&tmp); 0105 /* floatnum2longint rounds, we have to truncate first */ 0106 float_copy(&tmp, x, digits); 0107 if (float_getsign(x) < 0) 0108 float_add(&tmp, &tmp, &c1, EXACT); 0109 _floatnum2longint(longint, &tmp); 0110 float_free(&tmp); 0111 if (_bitlength(longint) > LOGICRANGE) 0112 return 0; 0113 } 0114 _zeroextend(longint); 0115 if (float_getsign(x) < 0) 0116 _not(longint); 0117 return 1; 0118 } 0119 0120 void 0121 _logic2floatnum( 0122 floatnum f, 0123 t_longint* longint) 0124 { 0125 int idx; 0126 signed char sign; 0127 0128 sign = _signextend(longint); 0129 if (sign < 0) 0130 _neg(longint); 0131 idx = MAXIDX; 0132 while (idx >= 0 && longint->value[idx] == 0) 0133 --idx; 0134 if (idx < 0) 0135 longint->length = 0; 0136 else 0137 longint->length = idx + 1; 0138 _longint2floatnum(f, longint); 0139 float_setsign(f, sign); 0140 } 0141 0142 void 0143 _not( 0144 t_longint* longint) 0145 { 0146 int idx; 0147 0148 for (idx = -1; ++idx <= (int)MAXIDX;) 0149 longint->value[idx] = ~(longint->value[idx]); 0150 } 0151 0152 void 0153 _and( 0154 t_longint* x1, 0155 t_longint* x2) 0156 { 0157 int idx; 0158 0159 for (idx = -1; ++idx <= (int)MAXIDX;) 0160 x1->value[idx] = x1->value[idx] & x2->value[idx]; 0161 } 0162 0163 void 0164 _or( 0165 t_longint* x1, 0166 t_longint* x2) 0167 { 0168 int idx; 0169 0170 for (idx = -1; ++idx <= (int)MAXIDX;) 0171 x1->value[idx] = x1->value[idx] | x2->value[idx]; 0172 } 0173 0174 void 0175 _xor( 0176 t_longint* x1, 0177 t_longint* x2) 0178 { 0179 int idx; 0180 0181 for (idx = -1; ++idx <= (int)MAXIDX;) 0182 x1->value[idx] = x1->value[idx] ^ x2->value[idx]; 0183 } 0184 0185 void 0186 _shr( 0187 t_longint* x, 0188 unsigned shift) 0189 { 0190 int idx; 0191 const unsigned sign = _signof(x) < 0? ~0 : 0; 0192 const int moves = shift/BITS_IN_UNSIGNED; 0193 const int maxidx = MAXIDX; 0194 0195 if (moves > 0) 0196 { 0197 shift -= moves * BITS_IN_UNSIGNED; 0198 for (idx = moves-1; ++idx <= maxidx;) 0199 x->value[idx-moves] = x->value[idx]; 0200 idx = MAXIDX - moves + 1; 0201 if (idx < 0) 0202 idx = 0; 0203 for (; idx <= maxidx; ++idx) 0204 x->value[idx] = sign; 0205 } 0206 if (shift > 0) 0207 { 0208 for (idx = -1; ++idx < maxidx;) 0209 x->value[idx] = _longshr(x->value[idx], x->value[idx+1], shift); 0210 x->value[MAXIDX] = _longshr(x->value[MAXIDX], sign, shift); 0211 } 0212 } 0213 0214 void 0215 _shl( 0216 t_longint* x, 0217 unsigned shift) 0218 { 0219 int moves, idx; 0220 0221 moves = shift/BITS_IN_UNSIGNED; 0222 if (moves > 0) 0223 { 0224 shift -= moves * BITS_IN_UNSIGNED; 0225 for (idx = MAXIDX; idx >= moves; --idx) 0226 x->value[idx] = x->value[idx-moves]; 0227 if (moves > (int)MAXIDX) 0228 moves = MAXIDX+1; 0229 for (idx = -1; ++idx < moves;) 0230 x->value[idx] = 0; 0231 } 0232 if (shift > 0) 0233 { 0234 for (idx = MAXIDX; idx > 0; --idx) 0235 x->value[idx] = _longshl(x->value[idx-1], x->value[idx], shift); 0236 x->value[0] <<= shift; 0237 } 0238 }