Integer Conversion.swift 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. //
  2. // Integer Conversion.swift
  3. // BigInt
  4. //
  5. // Created by Károly Lőrentey on 2017-08-11.
  6. // Copyright © 2016-2017 Károly Lőrentey.
  7. //
  8. extension BigUInt {
  9. public init?<T: BinaryInteger>(exactly source: T) {
  10. guard source >= (0 as T) else { return nil }
  11. if source.bitWidth <= 2 * Word.bitWidth {
  12. var it = source.words.makeIterator()
  13. self.init(low: it.next() ?? 0, high: it.next() ?? 0)
  14. precondition(it.next() == nil, "Length of BinaryInteger.words is greater than its bitWidth")
  15. }
  16. else {
  17. self.init(words: source.words)
  18. }
  19. }
  20. public init<T: BinaryInteger>(_ source: T) {
  21. precondition(source >= (0 as T), "BigUInt cannot represent negative values")
  22. self.init(exactly: source)!
  23. }
  24. public init<T: BinaryInteger>(truncatingIfNeeded source: T) {
  25. self.init(words: source.words)
  26. }
  27. public init<T: BinaryInteger>(clamping source: T) {
  28. if source <= (0 as T) {
  29. self.init()
  30. }
  31. else {
  32. self.init(words: source.words)
  33. }
  34. }
  35. }
  36. extension BigInt {
  37. public init() {
  38. self.init(sign: .plus, magnitude: 0)
  39. }
  40. /// Initializes a new signed big integer with the same value as the specified unsigned big integer.
  41. public init(_ integer: BigUInt) {
  42. self.magnitude = integer
  43. self.sign = .plus
  44. }
  45. public init<T>(_ source: T) where T : BinaryInteger {
  46. if source >= (0 as T) {
  47. self.init(sign: .plus, magnitude: BigUInt(source))
  48. }
  49. else {
  50. var words = Array(source.words)
  51. words.twosComplement()
  52. self.init(sign: .minus, magnitude: BigUInt(words: words))
  53. }
  54. }
  55. public init?<T>(exactly source: T) where T : BinaryInteger {
  56. self.init(source)
  57. }
  58. public init<T>(clamping source: T) where T : BinaryInteger {
  59. self.init(source)
  60. }
  61. public init<T>(truncatingIfNeeded source: T) where T : BinaryInteger {
  62. self.init(source)
  63. }
  64. }
  65. extension BigUInt: ExpressibleByIntegerLiteral {
  66. /// Initialize a new big integer from an integer literal.
  67. public init(integerLiteral value: UInt64) {
  68. self.init(value)
  69. }
  70. }
  71. extension BigInt: ExpressibleByIntegerLiteral {
  72. /// Initialize a new big integer from an integer literal.
  73. public init(integerLiteral value: Int64) {
  74. self.init(value)
  75. }
  76. }