77bin binAdd (const bin x , const bin y ) {
88 bin r = binZERO ;
99 bin_int_t carry = 0 ;
10-
10+
1111 for (bin_int_t i = 0 ; i < BIN_BITS ; i ++ ) {
1212 bin_int_t sum = x .bits [i ] + y .bits [i ] + carry ;
13- r .bits [i ] = sum & 1 ; // Extract least significant bit
14- carry = sum >> 1 ; // Extract carry bit
13+ r .bits [i ] = sum % 2 ; // Extract least significant bit (check if odd)
14+ carry = sum / 2 ; // Extract carry bit (divide by 2)
1515 }
1616
1717 // Check for overflow
@@ -112,18 +112,18 @@ bin binModulus(const bin x, const bin y) {
112112
113113 if (binLT (x , y ))
114114 return x ;
115-
115+
116116 // Use the same algorithm as division but return remainder instead
117117 bin remainder = binZERO ;
118-
118+
119119 for (int i = BIN_BITS - 1 ; i >= 0 ; -- i ) {
120120 remainder = binShiftL1 (remainder );
121121 remainder .bits [0 ] = x .bits [i ];
122-
122+
123123 if (binGTEQ (remainder , y ))
124124 remainder = binSubtract (remainder , y );
125125 }
126-
126+
127127 return remainder ;
128128}
129129
@@ -134,7 +134,7 @@ bin binPow(const bin x, const bin y) {
134134 return binONE ;
135135 else if (binEQOne (y ))
136136 return x ;
137-
137+
138138 // Use binary exponentiation (square and multiply)
139139 bin result = binONE ;
140140 bin base = x ;
@@ -146,7 +146,7 @@ bin binPow(const bin x, const bin y) {
146146 base = binMultiply (base , base );
147147 exponent = binShiftR1 (exponent );
148148 }
149-
149+
150150 return result ;
151151}
152152
@@ -156,39 +156,39 @@ bin binSqrt(const bin x) {
156156 return binZERO ;
157157 else if (binEQOne (x ))
158158 return binONE ;
159-
159+
160160 // Use Newton-Raphson method: x_{n+1} = (x_n + a/x_n) / 2
161161 // Start with x/2 as initial guess
162162 bin guess = binShiftR1 (x );
163163 bin prev_guess ;
164164 bin_int_t iterations = 0 ;
165165 const bin_int_t max_iterations = 30 ; // Prevent infinite loops
166-
166+
167167 do {
168168 prev_guess = guess ;
169-
169+
170170 // Calculate a/guess
171171 bin quotient = binDivide (x , guess );
172-
172+
173173 // Calculate (guess + a/guess) / 2
174174 bin sum = binAdd (guess , quotient );
175175 guess = binShiftR1 (sum );
176-
176+
177177 iterations ++ ;
178-
178+
179179 // Stop if we've converged or hit max iterations
180180 } while (!binEQ (guess , prev_guess ) && iterations < max_iterations );
181-
181+
182182 return guess ;
183183}
184184
185185// Calculate the base2 logarithm of a binary number
186186bin binLog2 (const bin x ) {
187187 assert (!binEQZero (x )); // log2(0) is undefined
188-
188+
189189 if (binEQOne (x ))
190190 return binZERO ; // log2(1) = 0
191-
191+
192192 // Find the position of the most significant bit (MSB)
193193 // This gives us the integer part of log2(x)
194194 return binMSBi (x );
@@ -198,24 +198,24 @@ bin binLog2(const bin x) {
198198// Calculate the base10 logarithm of a binary number
199199bin binLog10 (const bin x ) {
200200 assert (!binEQZero (x )); // log10(0) is undefined
201-
201+
202202 if (binEQOne (x ))
203203 return binZERO ; // log10(1) = 0
204-
204+
205205 // Use a lookup table approach for common values
206206 // For values 1-1000, we can pre-calculate log10
207207 if (binLTEQ (x , binNew (1000 ))) {
208208 // Simple lookup table for powers of 10 and common values
209209 if (binEQ (x , binNew (10 ))) return binNew (1 );
210210 if (binEQ (x , binNew (100 ))) return binNew (2 );
211211 if (binEQ (x , binNew (1000 ))) return binNew (3 );
212-
212+
213213 // For other values, find the largest power of 10 that fits
214214 if (binGTEQ (x , binNew (100 ))) return binNew (2 );
215215 if (binGTEQ (x , binNew (10 ))) return binNew (1 );
216216 return binZERO ; // x < 10
217217 }
218-
218+
219219 // For larger values, use a different approach
220220 // Count the number of digits in base 10 representation
221221 bin temp = x ;
@@ -224,7 +224,7 @@ bin binLog10(const bin x) {
224224 temp = binDivide (temp , binNew (10 ));
225225 digit_count ++ ;
226226 }
227-
227+
228228 // log10(x) is approximately (number of digits - 1)
229229 return binNew (digit_count - 1 );
230230}
@@ -234,17 +234,17 @@ bin binLog10(const bin x) {
234234// This is a simplified integer-based approach that maintains the constraint-based design
235235bin binLog (const bin x ) {
236236 assert (!binEQZero (x )); // log(0) is undefined
237-
237+
238238 if (binEQOne (x ))
239239 return binZERO ; // log(1) = 0
240-
240+
241241 // For integer natural logarithm, we use a simple approximation:
242242 // ln(x) ≈ ln(2) * log2(x) where ln(2) ≈ 0.693
243243 // Since we're working with integers, we'll use a scaled approach
244-
244+
245245 // Get the log2 value (MSB position)
246246 bin log2_val = binLog2 (x );
247-
247+
248248 // Simple lookup table approach for small values (more accurate)
249249 if (binLTEQ (x , binNew (16 ))) {
250250 // Pre-calculated ln(x) values scaled by 1 (rounded to nearest integer)
@@ -256,15 +256,15 @@ bin binLog(const bin x) {
256256 else if (x_int <= 12 ) return binNew (2 );
257257 else return binNew (3 );
258258 }
259-
259+
260260 // For larger values, use the approximation ln(x) ≈ 0.7 * log2(x)
261261 // We'll use integer arithmetic: ln(x) ≈ (7 * log2(x)) / 10
262262 // But since we need integer results, we'll round: ln(x) ≈ (7 * log2(x) + 5) / 10
263-
263+
264264 bin seven = binNew (7 );
265265 bin ten = binNew (10 );
266266 bin five = binNew (5 );
267-
267+
268268 // Calculate (7 * log2_val + 5) / 10
269269 bin scaled = binAdd (binMultiply (seven , log2_val ), five );
270270 return binDivide (scaled , ten );
0 commit comments