@@ -380,6 +380,107 @@ size_t intn_addmnu(
380
380
return i ;
381
381
}
382
382
383
+ static void cond_neg (
384
+ intn_integer_sign_t sign , const intn_digit_t in [], size_t in_len , intn_digit_t out [])
385
+ {
386
+ if (sign == IntNPositiveInteger ) {
387
+ memcpy (out , in , sizeof (intn_digit_t ) * in_len );
388
+ } else {
389
+ uint32_t carry = 1 ;
390
+ for (size_t i = 0 ; i < in_len ; i ++ ) {
391
+ uint64_t temp = (uint64_t ) (~in [i ]) + (uint64_t ) carry ;
392
+ out [i ] = (uint32_t ) temp ;
393
+ carry = temp >> 32 ;
394
+ }
395
+ }
396
+ }
397
+
398
+ static size_t prepare_out (const intn_digit_t m [], size_t m_len , intn_integer_sign_t m_sign ,
399
+ const intn_digit_t n [], size_t n_len , intn_integer_sign_t n_sign , const intn_digit_t * b [],
400
+ size_t * b_len , intn_integer_sign_t * b_sign , intn_digit_t out [])
401
+ {
402
+ const intn_digit_t * longest ;
403
+ size_t longest_len ;
404
+ intn_integer_sign_t longest_sign ;
405
+
406
+ if (m_len > n_len ) {
407
+ longest = m ;
408
+ longest_len = m_len ;
409
+ longest_sign = m_sign ;
410
+ * b = n ;
411
+ * b_len = n_len ;
412
+ * b_sign = n_sign ;
413
+ } else {
414
+ longest = n ;
415
+ longest_len = n_len ;
416
+ longest_sign = n_sign ;
417
+ * b = m ;
418
+ * b_len = m_len ;
419
+ * b_sign = m_sign ;
420
+ }
421
+
422
+ cond_neg (longest_sign , longest , longest_len , out );
423
+ if (longest_sign == IntNPositiveInteger ) {
424
+ out [longest_len ] = 0 ;
425
+ } else {
426
+ out [longest_len ] = UINT32_MAX ;
427
+ }
428
+ return longest_len + 1 ;
429
+ }
430
+
431
+ static inline uint32_t bit_op (uint32_t a , uint32_t b ) { return a | b ; }
432
+
433
+ static inline size_t neg_and_bitwise (const intn_digit_t b [], size_t b_len ,
434
+ intn_integer_sign_t b_sign , intn_digit_t out [], size_t out_len )
435
+ {
436
+ if (b_sign == IntNPositiveInteger ) {
437
+ for (size_t i = 0 ; i < b_len ; i ++ ) {
438
+ out [i ] = bit_op (out [i ], b [i ]);
439
+ }
440
+ for (size_t i = b_len ; i < out_len ; i ++ ) {
441
+ out [i ] = bit_op (out [i ], 0 );
442
+ }
443
+ } else {
444
+ uint32_t carry = 1 ;
445
+ for (size_t i = 0 ; i < b_len ; i ++ ) {
446
+ uint64_t temp = (uint64_t ) (~b [i ]) + (uint64_t ) carry ;
447
+ out [i ] = bit_op (out [i ], (uint32_t ) temp );
448
+ carry = temp >> 32 ;
449
+ }
450
+ if (b_len < out_len ) {
451
+ out [b_len ] = bit_op (out [b_len ], (UINT32_MAX ) + carry );
452
+ }
453
+ for (size_t i = b_len + 1 ; i < out_len ; i ++ ) {
454
+ out [i ] = bit_op (out [i ], UINT32_MAX );
455
+ }
456
+ }
457
+ return out_len ;
458
+ }
459
+
460
+ size_t intn_bormn (const intn_digit_t m [], size_t m_len , intn_integer_sign_t m_sign ,
461
+ const intn_digit_t n [], size_t n_len , intn_integer_sign_t n_sign , intn_digit_t out [],
462
+ intn_integer_sign_t * out_sign )
463
+ {
464
+ intn_digit_t working_buf [INTN_MAX_IN_LEN + 1 ];
465
+
466
+ const intn_digit_t * b ;
467
+ size_t b_len ;
468
+ intn_integer_sign_t b_sign ;
469
+
470
+ size_t count
471
+ = prepare_out (m , m_len , m_sign , n , n_len , n_sign , & b , & b_len , & b_sign , working_buf );
472
+
473
+ neg_and_bitwise (b , b_len , b_sign , working_buf , count );
474
+
475
+ * out_sign = (intn_integer_sign_t ) ((unsigned int ) m_sign | (unsigned int ) n_sign )
476
+ & IntNNegativeInteger ;
477
+
478
+ size_t ret_count = count ; // MAX(count, count2);
479
+ cond_neg (* out_sign , working_buf , ret_count , out );
480
+
481
+ return ret_count ;
482
+ }
483
+
383
484
size_t intn_count_digits (const intn_digit_t * num , size_t num_len )
384
485
{
385
486
int i ;
0 commit comments