35
35
#define MIN (a , b ) (((a) < (b)) ? (a) : (b))
36
36
#define MAX (a , b ) (((a) > (b)) ? (a) : (b))
37
37
38
+ static size_t cond_neg_in_place (intn_integer_sign_t sign , intn_digit_t out []);
39
+ static size_t neg_in_place (intn_digit_t out [], size_t len );
40
+
38
41
/*
39
42
* Multiplication
40
43
*/
@@ -380,18 +383,23 @@ size_t intn_addmnu(
380
383
return i ;
381
384
}
382
385
386
+ static void neg (const intn_digit_t in [], size_t in_len , intn_digit_t out [])
387
+ {
388
+ uint32_t carry = 1 ;
389
+ for (size_t i = 0 ; i < in_len ; i ++ ) {
390
+ uint64_t temp = (uint64_t ) (~in [i ]) + (uint64_t ) carry ;
391
+ out [i ] = (uint32_t ) temp ;
392
+ carry = temp >> 32 ;
393
+ }
394
+ }
395
+
383
396
static void cond_neg (
384
397
intn_integer_sign_t sign , const intn_digit_t in [], size_t in_len , intn_digit_t out [])
385
398
{
386
399
if (sign == IntNPositiveInteger ) {
387
400
memcpy (out , in , sizeof (intn_digit_t ) * in_len );
388
401
} 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
- }
402
+ neg (in , in_len , out );
395
403
}
396
404
}
397
405
@@ -604,21 +612,15 @@ size_t intn_bsl(const uint32_t num[], size_t len, size_t n, uint32_t *out)
604
612
return initial_zeros + i ;
605
613
}
606
614
607
- size_t intn_bsr (const uint32_t num [], size_t len , size_t n , uint32_t * out )
615
+ size_t bsru (const uint32_t num [], size_t effective_bits_len , size_t n , uint32_t last_digit , uint32_t * out )
608
616
{
609
617
size_t digit_bit_size = sizeof (uint32_t ) * 8 ;
610
618
611
619
size_t digit_right_bit_shift = n % 32 ;
612
620
size_t left_shift_n = (32 - digit_right_bit_shift );
613
621
614
- size_t counted_digits = intn_count_digits (num , len );
615
- size_t ms_digit_bits = 32 - uint32_nlz (num [counted_digits - 1 ]);
616
- size_t effective_bits_len = (counted_digits - 1 ) * digit_bit_size + ms_digit_bits ;
617
-
618
- if (n > effective_bits_len ) {
619
- out [0 ] = 0 ;
620
- return 1 ;
621
- }
622
+ size_t len = size_round_to (effective_bits_len , digit_bit_size ) / digit_bit_size ;
623
+ size_t counted_digits = len ;
622
624
623
625
///size_t new_bits_len = size_round_to(effective_bits_len - n, digit_bit_size);
624
626
@@ -637,7 +639,7 @@ size_t intn_bsr(const uint32_t num[], size_t len, size_t n, uint32_t *out)
637
639
uint32_t digit = num [i ];
638
640
out [i - discarded ] = (digit >> digit_right_bit_shift ) | (next_digit << left_shift_n );
639
641
}
640
- uint32_t maybe_last_out = (num [i ] >> digit_right_bit_shift );
642
+ uint32_t maybe_last_out = (num [i ] >> digit_right_bit_shift ) | ( last_digit << left_shift_n ) ;
641
643
642
644
/*
643
645
if (initial_zeros + i > new_digits_count) {
@@ -653,6 +655,35 @@ size_t intn_bsr(const uint32_t num[], size_t len, size_t n, uint32_t *out)
653
655
return i - discarded ;
654
656
}
655
657
658
+ size_t intn_bsr (const uint32_t num [], size_t len , intn_integer_sign_t num_sign , size_t n , uint32_t * out )
659
+ {
660
+ size_t digit_bit_size = sizeof (uint32_t ) * 8 ;
661
+ size_t counted_digits = intn_count_digits (num , len );
662
+ size_t ms_digit_bits = 32 - uint32_nlz (num [counted_digits - 1 ]);
663
+ size_t effective_bits_len = (counted_digits - 1 ) * digit_bit_size + ms_digit_bits ;
664
+
665
+ if (n > effective_bits_len ) {
666
+ out [0 ] = (num_sign == IntNPositiveInteger ) ? 0 : 1 ;
667
+ return 1 ;
668
+ }
669
+
670
+ if (num_sign == IntNPositiveInteger ) {
671
+ return bsru (num , effective_bits_len , n , 0 , out );
672
+ } else {
673
+ uint32_t tmp_buf [INTN_MAX_RES_LEN ];
674
+ memset (out , 0 , INTN_MAX_RES_LEN * sizeof (const uint32_t ));
675
+ neg (num , counted_digits , tmp_buf );
676
+ size_t shifted_len = bsru (tmp_buf , effective_bits_len , n , (uint32_t ) -1 , out );
677
+
678
+ size_t len = size_round_to (effective_bits_len - n , digit_bit_size ) / digit_bit_size ;
679
+ neg_in_place (out , len );
680
+
681
+ fprintf (stderr , "shifted: %i, len: %i\n" , (int ) shifted_len , (int ) len );
682
+ print_num (out , len );
683
+ return len ;
684
+ }
685
+ }
686
+
656
687
657
688
658
689
/*
@@ -912,26 +943,32 @@ int intn_parse(
912
943
return out_len ;
913
944
}
914
945
946
+ static size_t neg_in_place (intn_digit_t out [], size_t len )
947
+ {
948
+ uint32_t carry = 1 ;
949
+ size_t i ;
950
+ int last_non_zero = -1 ;
951
+ for (i = 0 ; i < len ; i ++ ) {
952
+ uint64_t temp = (uint64_t ) (~out [i ]) + (uint64_t ) carry ;
953
+ if ((uint32_t ) temp != 0 ) {
954
+ last_non_zero = i ;
955
+ }
956
+ out [i ] = (uint32_t ) temp ;
957
+ carry = temp >> 32 ;
958
+ }
959
+ if (carry ) {
960
+ abort ();
961
+ out [i ] = carry ;
962
+ return i ;
963
+ } else {
964
+ return last_non_zero + 1 ;
965
+ }
966
+ }
967
+
915
968
static size_t cond_neg_in_place (intn_integer_sign_t sign , intn_digit_t out [])
916
969
{
917
970
if (sign == IntNNegativeInteger ) {
918
- uint32_t carry = 1 ;
919
- size_t i ;
920
- int last_non_zero = -1 ;
921
- for (i = 0 ; i < INTN_MAX_RES_LEN - 1 ; i ++ ) {
922
- uint64_t temp = (uint64_t ) (~out [i ]) + (uint64_t ) carry ;
923
- if ((uint32_t ) temp != 0 ) {
924
- last_non_zero = i ;
925
- }
926
- out [i ] = (uint32_t ) temp ;
927
- carry = temp >> 32 ;
928
- }
929
- if (carry ) {
930
- out [i ] = carry ;
931
- return i ;
932
- } else {
933
- return last_non_zero + 1 ;
934
- }
971
+ return neg_in_place (out , INTN_MAX_RES_LEN - 1 );
935
972
} else {
936
973
return intn_count_digits (out , INTN_MAX_IN_LEN );
937
974
}
0 commit comments