Decimal128.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright 2020 Realm Inc.
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. //
  17. ////////////////////////////////////////////////////////////////////////////
  18. import Foundation
  19. import Realm
  20. /**
  21. A 128-bit IEEE 754-2008 decimal floating point number.
  22. This type is similar to Swift's built-in Decimal type, but allocates bits differently, resulting in a different representable range. (NS)Decimal stores a significand of up to 38 digits long and an exponent from -128 to 127, while this type stores up to 34 digits of significand and an exponent from -6143 to 6144.
  23. */
  24. @objc(RealmSwiftDecimal128)
  25. public final class Decimal128: RLMDecimal128, Decodable, @unchecked Sendable {
  26. /// Creates a new zero-initialized Decimal128.
  27. public override required init() {
  28. super.init()
  29. }
  30. /// Converts the given value to a Decimal128.
  31. ///
  32. /// The following types can be converted to Decimal128:
  33. /// - Int (of any size)
  34. /// - Float
  35. /// - Double
  36. /// - String
  37. /// - NSNumber
  38. /// - Decimal
  39. ///
  40. /// Passing a value with a type not in this list is a fatal error. Passing a string which cannot be parsed as a valid Decimal128 is a fatal error.
  41. ///
  42. /// - parameter value: The value to convert to a Decimal128.
  43. public override required init(value: Any) {
  44. super.init(value: value)
  45. }
  46. /// Converts the given number to a Decimal128.
  47. ///
  48. /// This initializer cannot fail and is never lossy.
  49. ///
  50. /// - parameter number: The number to convert to a Decimal128.
  51. public override required init(number: NSNumber) {
  52. super.init(number: number)
  53. }
  54. /// Parse the given string as a Decimal128.
  55. ///
  56. /// This initializer never throws and is marked as `throws` only because removing it is a breaking
  57. /// change. Strings which cannot be parsed as a Decimal128 return a value where `isNaN` is `true`.
  58. ///
  59. /// - parameter string: The string to parse.
  60. public override required init(string: String) throws {
  61. try super.init(string: string)
  62. }
  63. /// Creates a new Decimal128 by decoding from the given decoder.
  64. ///
  65. /// This initializer throws an error if the decoder is invalid or does not decode to a value which can be converted to Decimal128.
  66. ///
  67. /// - Parameter decoder: The decoder to read data from.
  68. public required init(from decoder: Decoder) throws {
  69. let container = try decoder.singleValueContainer()
  70. if let strValue = try? container.decode(String.self) {
  71. try super.init(string: strValue)
  72. } else if let intValue = try? container.decode(Int64.self) {
  73. super.init(number: intValue as NSNumber)
  74. } else if let doubleValue = try? container.decode(Double.self) {
  75. super.init(number: doubleValue as NSNumber)
  76. } else {
  77. throw DecodingError.dataCorruptedError(in: container, debugDescription: "Cannot convert value to Decimal128")
  78. }
  79. }
  80. /// The mininum value for Decimal128
  81. public static var min: Decimal128 {
  82. unsafeDowncast(__minimumDecimalNumber, to: Self.self)
  83. }
  84. /// The maximum value for Decimal128
  85. public static var max: Decimal128 {
  86. unsafeDowncast(__maximumDecimalNumber, to: Self.self)
  87. }
  88. }
  89. extension Decimal128: Encodable {
  90. /// Encodes this Decimal128 to the given encoder.
  91. ///
  92. /// This function throws an error if the given encoder is unable to encode a string.
  93. ///
  94. /// - Parameter encoder: The encoder to write data to.
  95. public func encode(to encoder: Encoder) throws {
  96. try self.stringValue.encode(to: encoder)
  97. }
  98. }
  99. extension Decimal128: ExpressibleByIntegerLiteral {
  100. /// Creates a new Decimal128 from the given integer literal.
  101. public convenience init(integerLiteral value: Int64) {
  102. self.init(number: value as NSNumber)
  103. }
  104. }
  105. extension Decimal128: ExpressibleByFloatLiteral {
  106. /// Creates a new Decimal128 from the given float literal.
  107. public convenience init(floatLiteral value: Double) {
  108. self.init(number: value as NSNumber)
  109. }
  110. }
  111. extension Decimal128: ExpressibleByStringLiteral {
  112. /// Creates a new Decimal128 from the given string literal.
  113. ///
  114. /// Aborts if the string cannot be parsed as a Decimal128.
  115. public convenience init(stringLiteral value: String) {
  116. try! self.init(string: value)
  117. }
  118. }
  119. extension Decimal128: Comparable {
  120. /// Returns a Boolean value indicating whether two decimal128 values are equal.
  121. ///
  122. /// - Parameters:
  123. /// - lhs: A Decimal128 value to compare.
  124. /// - rhs: Another Decimal128 value to compare.
  125. public static func == (lhs: Decimal128, rhs: Decimal128) -> Bool {
  126. lhs.isEqual(rhs)
  127. }
  128. /// Returns a Boolean value indicating whether the decimal128 value of the first
  129. /// argument is less than that of the second argument.
  130. ///
  131. /// - Parameters:
  132. /// - lhs: A Decimal128 value to compare.
  133. /// - rhs: Another Decimal128 value to compare.
  134. public static func < (lhs: Decimal128, rhs: Decimal128) -> Bool {
  135. lhs.isLessThan(rhs)
  136. }
  137. /// Returns a Boolean value indicating whether the decimal128 value of the first
  138. /// argument is less than or equal to that of the second argument.
  139. ///
  140. /// - Parameters:
  141. /// - lhs: A Decimal128 value to compare.
  142. /// - rhs: Another Decimal128 value to compare.
  143. public static func <= (lhs: Decimal128, rhs: Decimal128) -> Bool {
  144. lhs.isLessThanOrEqual(to: rhs)
  145. }
  146. /// Returns a Boolean value indicating whether the decimal128 value of the first
  147. /// argument is greater than or equal to that of the second argument.
  148. ///
  149. /// - Parameters:
  150. /// - lhs: A Decimal128 value to compare.
  151. /// - rhs: Another Decimal128 value to compare.
  152. public static func >= (lhs: Decimal128, rhs: Decimal128) -> Bool {
  153. lhs.isGreaterThanOrEqual(to: rhs)
  154. }
  155. /// Returns a Boolean value indicating whether the decimal128 value of the first
  156. /// argument is greater than that of the second argument.
  157. ///
  158. /// - Parameters:
  159. /// - lhs: A Decimal128 value to compare.
  160. /// - rhs: Another Decimal128 value to compare.
  161. public static func > (lhs: Decimal128, rhs: Decimal128) -> Bool {
  162. lhs.isGreaterThan(rhs)
  163. }
  164. }
  165. extension Decimal128: Numeric {
  166. /// Creates a new instance from the given integer, if it can be represented
  167. /// exactly.
  168. ///
  169. /// If the value passed as `source` is not representable exactly, the result
  170. /// is `nil`. In the following example, the constant `x` is successfully
  171. /// created from a value of `100`, while the attempt to initialize the
  172. /// constant `y` from `1_000` fails because the `Int8` type can represent
  173. /// `127` at maximum:
  174. ///
  175. /// - Parameter source: A value to convert to this type of integer.
  176. public convenience init?<T>(exactly source: T) where T: BinaryInteger {
  177. self.init(value: source)
  178. }
  179. /// A type that can represent the absolute value of Decimal128
  180. public typealias Magnitude = Decimal128
  181. /// The magnitude of this Decimal128.
  182. public var magnitude: Magnitude {
  183. unsafeDowncast(self.__magnitude, to: Magnitude.self)
  184. }
  185. /// Adds two decimal128 values and produces their sum.
  186. ///
  187. /// - Parameters:
  188. /// - lhs: The first Decimal128 value to add.
  189. /// - rhs: The second Decimal128 value to add.
  190. public static func + (lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
  191. unsafeDowncast(lhs.decimalNumber(byAdding: rhs), to: Decimal128.self)
  192. }
  193. /// Subtracts one Decimal128 value from another and produces their difference.
  194. ///
  195. /// - Parameters:
  196. /// - lhs: A Decimal128 value.
  197. /// - rhs: The Decimal128 value to subtract from `lhs`.
  198. public static func - (lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
  199. unsafeDowncast(lhs.decimalNumber(bySubtracting: rhs), to: Decimal128.self)
  200. }
  201. /// Multiplies two Decimal128 values and produces their product.
  202. ///
  203. /// - Parameters:
  204. /// - lhs: The first value to multiply.
  205. /// - rhs: The second value to multiply.
  206. public static func * (lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
  207. unsafeDowncast(lhs.decimalNumberByMultiplying(by: rhs), to: Decimal128.self)
  208. }
  209. /// Multiplies two values and stores the result in the left-hand-side
  210. /// variable.
  211. ///
  212. /// - Parameters:
  213. /// - lhs: The first value to multiply.
  214. /// - rhs: The second value to multiply.
  215. public static func *= (lhs: inout Decimal128, rhs: Decimal128) {
  216. lhs = lhs * rhs
  217. }
  218. /// Returns the quotient of dividing the first Decimal128 value by the second.
  219. ///
  220. /// - Parameters:
  221. /// - lhs: The Decimal128 value to divide.
  222. /// - rhs: The Decimal128 value to divide `lhs` by. `rhs` must not be zero.
  223. public static func / (lhs: Decimal128, rhs: Decimal128) -> Decimal128 {
  224. unsafeDowncast(lhs.decimalNumberByDividing(by: rhs), to: Decimal128.self)
  225. }
  226. }
  227. extension Decimal128 {
  228. /// A type that represents the distance between two values.
  229. public typealias Stride = Decimal128
  230. /// Returns the distance from this Decimal128 to the given value, expressed as a
  231. /// stride.
  232. ///
  233. /// - Parameter other: The Decimal128 value to calculate the distance to.
  234. /// - Returns: The distance from this value to `other`.
  235. public func distance(to other: Decimal128) -> Decimal128 {
  236. unsafeDowncast(other.decimalNumber(bySubtracting: self), to: Decimal128.self)
  237. }
  238. /// Returns a Decimal128 that is offset the specified distance from this value.
  239. ///
  240. /// Use the `advanced(by:)` method in generic code to offset a value by a
  241. /// specified distance. If you're working directly with numeric values, use
  242. /// the addition operator (`+`) instead of this method.
  243. ///
  244. /// - Parameter n: The distance to advance this Decimal128.
  245. /// - Returns: A Decimal128 that is offset from this value by `n`.
  246. public func advanced(by n: Decimal128) -> Decimal128 {
  247. unsafeDowncast(decimalNumber(byAdding: n), to: Decimal128.self)
  248. }
  249. }
  250. extension Decimal128 {
  251. /// `true` if `self` is a signaling NaN, `false` otherwise.
  252. public var isSignaling: Bool {
  253. self.isNaN
  254. }
  255. /// `true` if `self` is a signaling NaN, `false` otherwise.
  256. public var isSignalingNaN: Bool {
  257. self.isSignaling
  258. }
  259. }