| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- //
- // Bitwise Ops.swift
- // CS.BigInt
- //
- // Created by Károly Lőrentey on 2016-01-03.
- // Copyright © 2016-2017 Károly Lőrentey.
- //
- //MARK: Bitwise Operations
- extension CS.BigUInt {
- /// Return the ones' complement of `a`.
- ///
- /// - Complexity: O(a.count)
- public static prefix func ~(a: CS.BigUInt) -> CS.BigUInt {
- return CS.BigUInt(words: a.words.map { ~$0 })
- }
- /// Calculate the bitwise OR of `a` and `b`, and store the result in `a`.
- ///
- /// - Complexity: O(max(a.count, b.count))
- public static func |= (a: inout CS.BigUInt, b: CS.BigUInt) {
- a.reserveCapacity(b.count)
- for i in 0 ..< b.count {
- a[i] |= b[i]
- }
- }
- /// Calculate the bitwise AND of `a` and `b` and return the result.
- ///
- /// - Complexity: O(max(a.count, b.count))
- public static func &= (a: inout CS.BigUInt, b: CS.BigUInt) {
- for i in 0 ..< Swift.max(a.count, b.count) {
- a[i] &= b[i]
- }
- }
- /// Calculate the bitwise XOR of `a` and `b` and return the result.
- ///
- /// - Complexity: O(max(a.count, b.count))
- public static func ^= (a: inout CS.BigUInt, b: CS.BigUInt) {
- a.reserveCapacity(b.count)
- for i in 0 ..< b.count {
- a[i] ^= b[i]
- }
- }
- }
- extension CS.BigInt {
- public static prefix func ~(x: CS.BigInt) -> CS.BigInt {
- switch x.sign {
- case .plus:
- return CS.BigInt(sign: .minus, magnitude: x.magnitude + 1)
- case .minus:
- return CS.BigInt(sign: .plus, magnitude: x.magnitude - 1)
- }
- }
-
- public static func &(lhs: inout CS.BigInt, rhs: CS.BigInt) -> CS.BigInt {
- let left = lhs.words
- let right = rhs.words
- // Note we aren't using left.count/right.count here; we account for the sign bit separately later.
- let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count)
- var words: [UInt] = []
- words.reserveCapacity(count)
- for i in 0 ..< count {
- words.append(left[i] & right[i])
- }
- if lhs.sign == .minus && rhs.sign == .minus {
- words.twosComplement()
- return CS.BigInt(sign: .minus, magnitude: CS.BigUInt(words: words))
- }
- return CS.BigInt(sign: .plus, magnitude: CS.BigUInt(words: words))
- }
-
- public static func |(lhs: inout CS.BigInt, rhs: CS.BigInt) -> CS.BigInt {
- let left = lhs.words
- let right = rhs.words
- // Note we aren't using left.count/right.count here; we account for the sign bit separately later.
- let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count)
- var words: [UInt] = []
- words.reserveCapacity(count)
- for i in 0 ..< count {
- words.append(left[i] | right[i])
- }
- if lhs.sign == .minus || rhs.sign == .minus {
- words.twosComplement()
- return CS.BigInt(sign: .minus, magnitude: CS.BigUInt(words: words))
- }
- return CS.BigInt(sign: .plus, magnitude: CS.BigUInt(words: words))
- }
-
- public static func ^(lhs: inout CS.BigInt, rhs: CS.BigInt) -> CS.BigInt {
- let left = lhs.words
- let right = rhs.words
- // Note we aren't using left.count/right.count here; we account for the sign bit separately later.
- let count = Swift.max(lhs.magnitude.count, rhs.magnitude.count)
- var words: [UInt] = []
- words.reserveCapacity(count)
- for i in 0 ..< count {
- words.append(left[i] ^ right[i])
- }
- if (lhs.sign == .minus) != (rhs.sign == .minus) {
- words.twosComplement()
- return CS.BigInt(sign: .minus, magnitude: CS.BigUInt(words: words))
- }
- return CS.BigInt(sign: .plus, magnitude: CS.BigUInt(words: words))
- }
-
- public static func &=(lhs: inout CS.BigInt, rhs: CS.BigInt) {
- lhs = lhs & rhs
- }
-
- public static func |=(lhs: inout CS.BigInt, rhs: CS.BigInt) {
- lhs = lhs | rhs
- }
-
- public static func ^=(lhs: inout CS.BigInt, rhs: CS.BigInt) {
- lhs = lhs ^ rhs
- }
- }
|