3
3
// NumberKit
4
4
//
5
5
// Created by Matthias Zenger on 12/08/2015.
6
- // Copyright © 2015-2017 Matthias Zenger. All rights reserved.
6
+ // Copyright © 2015-2018 Matthias Zenger. All rights reserved.
7
7
//
8
8
// Licensed under the Apache License, Version 2.0 (the "License");
9
9
// you may not use this file except in compliance with the License.
@@ -45,7 +45,7 @@ public struct BigInt: Hashable,
45
45
46
46
// All internal computations are based on 32-bit words; the base of this representation
47
47
// is therefore `UInt32.max + 1`.
48
- private static let base : UInt64 = UInt64 ( UInt32 . max) + 1
48
+ private static let base : UInt64 = UInt64 ( UInt32 . max) & + 1
49
49
50
50
// `hiword` extracts the highest 32-bit value of a `UInt64`.
51
51
private static func hiword( _ num: UInt64 ) -> UInt32 {
@@ -59,7 +59,7 @@ public struct BigInt: Hashable,
59
59
60
60
// `joinwords` combines two words into a `UInt64` value.
61
61
private static func joinwords( _ lword: UInt32 , _ hword: UInt32 ) -> UInt64 {
62
- return ( UInt64 ( hword) << 32 ) + UInt64( lword)
62
+ return ( UInt64 ( hword) << 32 ) & + UInt64 ( lword)
63
63
}
64
64
65
65
/// Class `Base` defines a representation and type for the base used in computing
@@ -404,16 +404,16 @@ public struct BigInt: Hashable,
404
404
guard self . negative == rhs. negative else {
405
405
return self . negative ? - 1 : 1
406
406
}
407
- return self . negative ? rhs. compareDigits ( with: self ) : compareDigits ( with: rhs)
407
+ return self . negative ? rhs. compareDigits ( with: self ) : self . compareDigits ( with: rhs)
408
408
}
409
409
410
410
private func compareDigits( with rhs: BigInt ) -> Int {
411
- guard uwords. count == rhs. uwords. count else {
412
- return uwords. count < rhs. uwords. count ? - 1 : 1
411
+ guard self . uwords. count == rhs. uwords. count else {
412
+ return self . uwords. count < rhs. uwords. count ? - 1 : 1
413
413
}
414
- for i in 1 ... uwords. count {
415
- let a = uwords [ uwords. count - i]
416
- let b = rhs. uwords [ uwords. count - i]
414
+ for i in 1 ... self . uwords. count {
415
+ let a = self . uwords [ self . uwords. count - i]
416
+ let b = rhs. uwords [ self . uwords. count - i]
417
417
if a != b {
418
418
return a < b ? - 1 : 1
419
419
}
@@ -452,7 +452,7 @@ public struct BigInt: Hashable,
452
452
guard self . negative == rhs. negative else {
453
453
return self . plus ( rhs. negate)
454
454
}
455
- let cmp = compareDigits ( with: rhs)
455
+ let cmp = self . compareDigits ( with: rhs)
456
456
guard cmp != 0 else {
457
457
return 0
458
458
}
@@ -542,18 +542,18 @@ public struct BigInt: Hashable,
542
542
return true
543
543
}
544
544
545
- /// Divides `self` by `rhs` and returns the result as a `BigInt`.
545
+ /// Divides `self` by `rhs` and returns the quotient and the remainder as a `BigInt`.
546
546
public func divided( by rhs: BigInt ) -> ( quotient: BigInt , remainder: BigInt ) {
547
547
guard rhs. uwords. count <= self . uwords. count else {
548
- return ( BigInt ( 0 ) , self . abs )
548
+ return ( BigInt ( 0 ) , self )
549
549
}
550
550
let neg = self . negative != rhs. negative
551
551
if rhs. uwords. count == self . uwords. count {
552
- let cmp = compare ( to : rhs)
552
+ let cmp = self . compareDigits ( with : rhs)
553
553
if cmp == 0 {
554
554
return ( BigInt ( neg ? - 1 : 1 ) , BigInt ( 0 ) )
555
555
} else if cmp < 0 {
556
- return ( BigInt ( 0 ) , self . abs )
556
+ return ( BigInt ( 0 ) , self )
557
557
}
558
558
}
559
559
var rem = ContiguousArray < UInt32 > ( self . uwords)
@@ -618,6 +618,7 @@ public struct BigInt: Hashable,
618
618
}
619
619
620
620
/// Computes the bitwise `and` between this value and `rhs`.
621
+ /// The resulting number is negative if both operands are negative.
621
622
public func and( _ rhs: BigInt ) -> BigInt {
622
623
let size = Swift . min ( self . uwords. count, rhs. uwords. count)
623
624
var res = ContiguousArray < UInt32 > ( )
@@ -628,7 +629,8 @@ public struct BigInt: Hashable,
628
629
return BigInt ( words: res, negative: self . negative && rhs. negative)
629
630
}
630
631
631
- /// Computes the bitwise `or` between this value and `rhs`.
632
+ /// Computes the bitwise `or` (inclusive or) between this value and `rhs`.
633
+ /// The resulting number is negative if one of the two operands is negative.
632
634
public func or( _ rhs: BigInt ) -> BigInt {
633
635
let size = Swift . max ( self . uwords. count, rhs. uwords. count)
634
636
var res = ContiguousArray < UInt32 > ( )
@@ -641,7 +643,8 @@ public struct BigInt: Hashable,
641
643
return BigInt ( words: res, negative: self . negative || rhs. negative)
642
644
}
643
645
644
- /// Computes the bitwise `xor` between this value and `rhs`.
646
+ /// Computes the bitwise `xor` (exclusive or) between this value and `rhs`.
647
+ /// The resulting number is negative if one of the two operands is negative.
645
648
public func xor( _ rhs: BigInt ) -> BigInt {
646
649
let size = Swift . max ( self . uwords. count, rhs. uwords. count)
647
650
var res = ContiguousArray < UInt32 > ( )
@@ -654,7 +657,7 @@ public struct BigInt: Hashable,
654
657
return BigInt ( words: res, negative: self . negative || rhs. negative)
655
658
}
656
659
657
- /// Inverts the bits in this `BigInt`.
660
+ /// Inverts the bits in this `BigInt`. The sign gets inverted as well.
658
661
public var invert : BigInt {
659
662
var res = ContiguousArray < UInt32 > ( )
660
663
res. reserveCapacity ( self . uwords. count)
@@ -666,6 +669,7 @@ public struct BigInt: Hashable,
666
669
667
670
/// Shifts the bits in this `BigInt` to the left if `n` is positive, or to the right
668
671
/// if `n` is negative. Bits are shifted as if this `BigInt` is an unsigned number.
672
+ /// The sign gets preserved.
669
673
public func shift( _ n: Int ) -> BigInt {
670
674
if n < 0 {
671
675
return self . shiftRight ( - n)
@@ -710,6 +714,47 @@ public struct BigInt: Hashable,
710
714
}
711
715
return BigInt ( words: ContiguousArray < UInt32 > ( res. reversed ( ) ) , negative: self . negative)
712
716
}
717
+
718
+ /// Number of bits used to represent the (unsigned) `BigInt` number.
719
+ public var bitSize : Int {
720
+ return self . uwords. count * UInt32. bitWidth
721
+ }
722
+
723
+ /// Number of bits set in this `BigInt` number. The sign of the `BigInt` number gets ignored.
724
+ public var bitCount : Int {
725
+ var res = 0
726
+ for word in self . uwords {
727
+ res = res &+ bitcount ( word)
728
+ }
729
+ return res
730
+ }
731
+
732
+ /// Returns the number of trailing zero bits ignoring the sign.
733
+ public var trailingZeroBits : Int {
734
+ guard !self . isZero else {
735
+ return 0
736
+ }
737
+ var i = 0
738
+ while i < self . uwords. count && self . uwords [ i] == 0 {
739
+ i += 1
740
+ }
741
+ return i < self . uwords. count ? i * UInt32. bitWidth + self . uwords [ i] . trailingZeroBitCount
742
+ : i * UInt32. bitWidth
743
+ }
744
+
745
+ /// Returns the number of leading zero bits ignoring the sign.
746
+ public var leadingZeroBits : Int {
747
+ guard !self . isZero else {
748
+ return self . bitSize
749
+ }
750
+ var res = 0
751
+ var i = self . uwords. count - 1
752
+ while i >= 0 && self . uwords [ i] == 0 {
753
+ i -= 1
754
+ res += UInt32 . bitWidth
755
+ }
756
+ return i >= 0 ? res + self . uwords [ i] . leadingZeroBitCount : res
757
+ }
713
758
}
714
759
715
760
@@ -725,23 +770,36 @@ extension BigInt: IntegerNumber,
725
770
/// This is a signed type
726
771
public static let isSigned : Bool = true
727
772
728
- /// Returns the number of bits used to represent this `BigInt`. This consists of the
729
- /// words for representing the absolute value and one extra bit for representing the sign .
773
+ /// Returns the number of bits used to represent this `BigInt` assuming a binary representation
774
+ /// using the two-complement for negative numbers .
730
775
public var bitWidth : Int {
731
- return ( self . uwords . count * UInt32. bitWidth) + 1
776
+ return self . words . count * UInt32. bitWidth
732
777
}
733
778
734
- /// Returns the number of trailing zero bits in the representation of this `BigInt`.
779
+ /// Returns the number of trailing zero bits assuming a binary representation using the
780
+ /// two-complement for negative numbers.
735
781
public var trailingZeroBitCount : Int {
736
- guard !self . isZero else {
737
- return self . bitWidth
738
- }
782
+ let words = self . words
783
+ var res = 0
739
784
var i = 0
740
- while i < self . uwords . count && self . uwords [ i] == 0 {
785
+ while i < words . count && words [ i] == 0 {
741
786
i += 1
787
+ res += UInt . bitWidth
742
788
}
743
- return i < self . uwords. count ? i * UInt32. bitWidth + self . uwords [ i] . trailingZeroBitCount
744
- : i * UInt32. bitWidth
789
+ return i < words. count ? res + words[ i] . trailingZeroBitCount : res
790
+ }
791
+
792
+ /// Returns the number of leading zero bits assuming a binary representation using the
793
+ /// two-complement for negative numbers.
794
+ public var leadingZeroBitCount : Int {
795
+ let words = self . words
796
+ var res = 0
797
+ var i = words. count - 1
798
+ while i >= 0 && words [ i] == 0 {
799
+ i -= 1
800
+ res += UInt . bitWidth
801
+ }
802
+ return i >= 0 ? res + words[ i] . leadingZeroBitCount : res
745
803
}
746
804
747
805
/// Returns the words in the binary representation of the magnitude of this number in the
0 commit comments