Files
swift-mirror/test/Interpreter/SDK/NSDecimal.swift

120 lines
2.7 KiB
Swift

// RUN: %target-run-simple-swift | FileCheck %s
// REQUIRES: executable_test
// REQUIRES: objc_interop
import Foundation
extension NSDecimal {
init?(_ string: String) {
self.init()
let scanner = NSScanner(string: string)
if !scanner.scanDecimal(&self) {
return nil
}
}
}
enum NSDecimalResult: StringLiteralConvertible, Equatable, CustomStringConvertible {
case Some(NSDecimal)
case Error(NSCalculationError)
init() {
self = .Some(NSDecimal())
}
init(stringLiteral: String) {
if let value = NSDecimal(stringLiteral) {
self = .Some(value)
} else {
self = .Error(.lossOfPrecision)
}
}
init(unicodeScalarLiteral: String) {
self.init(stringLiteral: unicodeScalarLiteral)
}
init(extendedGraphemeClusterLiteral: String) {
self.init(stringLiteral: extendedGraphemeClusterLiteral)
}
var description: String {
switch self {
case .Some(var decimal):
return NSDecimalString(&decimal, nil)
case .Error:
return "NaN"
}
}
func pow10(power: Int) -> NSDecimalResult {
switch self {
case .Some(var decimal):
var result = NSDecimal()
let error = NSDecimalMultiplyByPowerOf10(&result, &decimal, Int16(power),
.roundPlain)
if error != .noError {
return .Error(error)
} else {
return .Some(result)
}
case .Error:
return self
}
}
}
func ==(x: NSDecimalResult, y: NSDecimalResult) -> Bool {
switch (x, y) {
case var (.Some(x1), .Some(x2)):
return NSDecimalCompare(&x1, &x2) == .orderedSame
default:
return false
}
}
func +(x: NSDecimalResult, y: NSDecimalResult) -> NSDecimalResult {
switch (x, y) {
case var (.Some(x1), .Some(y1)):
var result = NSDecimal()
let error = NSDecimalAdd(&result, &x1, &y1, .roundPlain)
if error != .noError {
return .Error(error)
} else {
return .Some(result)
}
case let (.Error(error), _):
return .Error(error)
case let (_, .Error(error)):
return .Error(error)
// FIXME rdar://problem/19165412
default:
fatalError("impossible")
}
}
let zero = NSDecimalResult()
print(zero) // CHECK: 0
let two: NSDecimalResult = "1" + "1"
print(two) // CHECK: 2
let point95: NSDecimalResult = "0.8" + "0.1" + "0.05"
print(point95) // CHECK: 0.95
let twoAgain = point95 + "1.05"
print(twoAgain) // CHECK: 2
print(two == twoAgain) // CHECK: true
print(two + "not a number") // CHECK: NaN
print(two + "not a number" == "still not a number") // CHECK: false
print(two + "not a number" == two) // CHECK: false
let one: NSDecimalResult = "1"
print(one.pow10(2)) // CHECK: 100
print(one.pow10(-2)) // CHECK: 0.01