// This source file is part of the Swift.org open source project
//
// Copyright (c) 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//

import CoreFoundation

public var NSDecimalMaxSize: Int32 { return 8 }
// Give a precision of at least 38 decimal digits, 128 binary positions.

public var NSDecimalNoScale: Int32 { return Int32(Int16.max) }

public struct Decimal {
    fileprivate static let maxSize: UInt32 = UInt32(NSDecimalMaxSize)
    fileprivate var __exponent: Int8
    fileprivate var __lengthAndFlags: UInt8
    fileprivate var __reserved: UInt16
    public var _exponent: Int32 {
        get {
            return Int32(__exponent)
        }
        set {
            __exponent = Int8(truncatingIfNeeded: newValue)
        }
    }
    // length == 0 && isNegative -> NaN
    public var _length: UInt32 {
        get {
            return UInt32((__lengthAndFlags & 0b0000_1111))
        }
        set {
            guard newValue <= maxMantissaLength else {
                fatalError("Attempt to set a length greater than capacity \(newValue) > \(maxMantissaLength)")
            }
            __lengthAndFlags =
                (__lengthAndFlags & 0b1111_0000) |
                UInt8(newValue & 0b0000_1111)
        }
    }
    public var _isNegative: UInt32 {
        get {
            return UInt32(((__lengthAndFlags) & 0b0001_0000) >> 4)
        }
        set {
            __lengthAndFlags =
                (__lengthAndFlags & 0b1110_1111) |
                (UInt8(newValue & 0b0000_0001 ) << 4)
        }
    }
    public var _isCompact: UInt32 {
        get {
            return UInt32(((__lengthAndFlags) & 0b0010_0000) >> 5)
        }
        set {
            __lengthAndFlags =
                (__lengthAndFlags & 0b1101_1111) |
                (UInt8(newValue & 0b0000_00001 ) << 5)
        }
    }
    public var _reserved: UInt32 {
        get {
            return UInt32(UInt32(__lengthAndFlags & 0b1100_0000) << 10 | UInt32(__reserved))
        }
        set {
            __lengthAndFlags =
                (__lengthAndFlags & 0b0011_1111) |
                UInt8(UInt32(newValue & (0b11 << 16)) >> 10)
            __reserved = UInt16(newValue & 0b1111_1111_1111_1111)
        }
    }
    public var _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)
    public init() {
        self._mantissa = (0,0,0,0,0,0,0,0)
        self.__exponent = 0
        self.__lengthAndFlags = 0
        self.__reserved = 0
    }

    fileprivate init(length: UInt32, mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)) {
        self._mantissa = mantissa
        self.__exponent = 0
        self.__lengthAndFlags = 0
        self.__reserved = 0
        self._length = length
    }

    public init(_exponent: Int32, _length: UInt32, _isNegative: UInt32, _isCompact: UInt32, _reserved: UInt32, _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)){
        self._mantissa = _mantissa
        self.__exponent = Int8(truncatingIfNeeded: _exponent)
        self.__lengthAndFlags = UInt8(_length & 0b1111)
        self.__reserved = 0
        self._isNegative = _isNegative
        self._isCompact = _isCompact
        self._reserved = _reserved
    }
}

extension Decimal {
    public static let leastFiniteMagnitude = Decimal(
        _exponent: 127,
        _length: 8,
        _isNegative: 1,
        _isCompact: 1,
        _reserved: 0,
        _mantissa: (0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
    )
    public static let greatestFiniteMagnitude = Decimal(
        _exponent: 127,
        _length: 8,
        _isNegative: 0,
        _isCompact: 1,
        _reserved: 0,
        _mantissa: (0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff)
    )
    public static let leastNormalMagnitude = Decimal(
        _exponent: -127,
        _length: 1,
        _isNegative: 0,
        _isCompact: 1,
        _reserved: 0,
        _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000)
    )
    public static let leastNonzeroMagnitude = Decimal(
        _exponent: -127,
        _length: 1,
        _isNegative: 0,
        _isCompact: 1,
        _reserved: 0,
        _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000)
    )
    public static let pi = Decimal(
        _exponent: -38,
        _length: 8,
        _isNegative: 0,
        _isCompact: 1,
        _reserved: 0,
        _mantissa: (0x6623, 0x7d57, 0x16e7, 0xad0d, 0xaf52, 0x4641, 0xdfa7, 0xec58)
    )
    public var exponent: Int {
        get {
            return Int(self.__exponent)
        }
    }
    public var significand: Decimal {
        get {
            return Decimal(_exponent: 0, _length: _length, _isNegative: _isNegative, _isCompact: _isCompact, _reserved: 0, _mantissa: _mantissa)
        }
    }
    public init(sign: FloatingPointSign, exponent: Int, significand: Decimal) {
        self.init(_exponent: Int32(exponent) + significand._exponent, _length: significand._length, _isNegative: sign == .plus ? 0 : 1, _isCompact: significand._isCompact, _reserved: 0, _mantissa: significand._mantissa)
    }
    public init(signOf: Decimal, magnitudeOf magnitude: Decimal) {
        self.init(_exponent: magnitude._exponent, _length: magnitude._length, _isNegative: signOf._isNegative, _isCompact: magnitude._isCompact, _reserved: 0, _mantissa: magnitude._mantissa)
    }
    public var sign: FloatingPointSign {
        return _isNegative == 0 ? FloatingPointSign.plus : FloatingPointSign.minus
    }
    public static var radix: Int {
        return 10
    }
    public var ulp: Decimal {
        if !self.isFinite { return Decimal.nan }
        return Decimal(_exponent: _exponent, _length: 8, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000))
    }
    public func isEqual(to other: Decimal) -> Bool {
        return self.compare(to: other) == .orderedSame
    }
    public func isLess(than other: Decimal) -> Bool {
        return self.compare(to: other) == .orderedAscending
    }
    public func isLessThanOrEqualTo(_ other: Decimal) -> Bool {
        let comparison = self.compare(to: other)
        return comparison == .orderedAscending || comparison == .orderedSame
    }
    public func isTotallyOrdered(belowOrEqualTo other: Decimal) -> Bool {
        // Notes: Decimal does not have -0 or infinities to worry about
        if self.isNaN {
            return false
        } else if self < other {
            return true
        } else if other < self {
            return false
        }
        // fall through to == behavior
        return true
    }
    public var isCanonical: Bool {
        return true
    }
    public var nextUp: Decimal {
        return self + Decimal(_exponent: _exponent, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000))
    }
    public var nextDown: Decimal {
        return self - Decimal(_exponent: _exponent, _length: 1, _isNegative: 0, _isCompact: 1, _reserved: 0, _mantissa: (0x0001, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000))
    }
}

extension Decimal : Hashable, Comparable {
    internal var doubleValue: Double {
        var d = 0.0
        if _length == 0 && _isNegative == 1 {
            return Double.nan
        }
        
        d = d * 65536 + Double(_mantissa.7)
        d = d * 65536 + Double(_mantissa.6)
        d = d * 65536 + Double(_mantissa.5)
        d = d * 65536 + Double(_mantissa.4)
        d = d * 65536 + Double(_mantissa.3)
        d = d * 65536 + Double(_mantissa.2)
        d = d * 65536 + Double(_mantissa.1)
        d = d * 65536 + Double(_mantissa.0)
        
        if _exponent < 0 {
            for _ in _exponent..<0 {
                d /= 10.0
            }
        } else {
            for _ in 0..<_exponent {
                d *= 10.0
            }
        }
        return _isNegative != 0 ? -d : d
    }
    public var hashValue: Int {
        return Int(bitPattern: __CFHashDouble(doubleValue))
    }
    public static func ==(lhs: Decimal, rhs: Decimal) -> Bool {
        if lhs.isNaN {
            return rhs.isNaN
        }
        if lhs.__exponent == rhs.__exponent && lhs.__lengthAndFlags == rhs.__lengthAndFlags && lhs.__reserved == rhs.__reserved {
            if lhs._mantissa.0 == rhs._mantissa.0 &&
                lhs._mantissa.1 == rhs._mantissa.1 &&
                lhs._mantissa.2 == rhs._mantissa.2 &&
                lhs._mantissa.3 == rhs._mantissa.3 &&
                lhs._mantissa.4 == rhs._mantissa.4 &&
                lhs._mantissa.5 == rhs._mantissa.5 &&
                lhs._mantissa.6 == rhs._mantissa.6 &&
                lhs._mantissa.7 == rhs._mantissa.7 {
                return true
            }
        }
        var lhsVal = lhs
        var rhsVal = rhs
        return NSDecimalCompare(&lhsVal, &rhsVal) == .orderedSame
    }
    public static func <(lhs: Decimal, rhs: Decimal) -> Bool {
        var lhsVal = lhs
        var rhsVal = rhs
        return NSDecimalCompare(&lhsVal, &rhsVal) == .orderedAscending
    }
}

extension Decimal : ExpressibleByFloatLiteral {
    public init(floatLiteral value: Double) {
        self.init(value)
    }
}

extension Decimal : ExpressibleByIntegerLiteral {
    public init(integerLiteral value: Int) {
        self.init(value)
    }
}

extension Decimal : SignedNumeric {
    public var magnitude: Decimal {
        return Decimal(_exponent: _exponent, _length: _length, _isNegative: 0, _isCompact: _isCompact, _reserved: 0, _mantissa: _mantissa)
    }

    // FIXME(integers): implement properly
    public init?<T : BinaryInteger>(exactly source: T) {
        fatalError()
    }

    public static func +=(_ lhs: inout Decimal, _ rhs: Decimal) {
        var leftOp = lhs
        var rightOp = rhs
        _ = NSDecimalAdd(&lhs, &leftOp, &rightOp, .plain)
    }

    public static func -=(_ lhs: inout Decimal, _ rhs: Decimal) {
        var leftOp = lhs
        var rightOp = rhs
        _ = NSDecimalSubtract(&lhs, &leftOp, &rightOp, .plain)
    }

    public static func *=(_ lhs: inout Decimal, _ rhs: Decimal) {
        var leftOp = lhs
        var rightOp = rhs
        _ = NSDecimalMultiply(&lhs, &leftOp, &rightOp, .plain)
    }

    public static func /=(_ lhs: inout Decimal, _ rhs: Decimal) {
        var leftOp = lhs
        var rightOp = rhs
        _ = NSDecimalDivide(&lhs, &leftOp, &rightOp, .plain)
    }

    public static func +(lhs: Decimal, rhs: Decimal) -> Decimal {
        var answer = lhs
        answer += rhs
        return answer;
    }

    public static func -(lhs: Decimal, rhs: Decimal) -> Decimal {
        var answer = lhs
        answer -= rhs
        return answer;
    }

    public static func /(lhs: Decimal, rhs: Decimal) -> Decimal {
        var answer = lhs
        answer /= rhs
        return answer;
    }

    public static func *(lhs: Decimal, rhs: Decimal) -> Decimal {
        var answer = lhs
        answer *= rhs
        return answer;
    }

    public mutating func negate() {
        guard _length != 0 else { return }
        _isNegative = _isNegative == 0 ? 1 : 0
    }
}

extension Decimal {
    @available(swift, obsoleted: 4, message: "Please use arithmetic operators instead")
    @_transparent
    public mutating func add(_ other: Decimal) {
        self += other
    }

    @available(swift, obsoleted: 4, message: "Please use arithmetic operators instead")
    @_transparent
    public mutating func subtract(_ other: Decimal) {
        self -= other
    }

    @available(swift, obsoleted: 4, message: "Please use arithmetic operators instead")
    @_transparent
    public mutating func multiply(by other: Decimal) {
        self *= other
    }

    @available(swift, obsoleted: 4, message: "Please use arithmetic operators instead")
    @_transparent
    public mutating func divide(by other: Decimal) {
        self /= other
    }
}

extension Decimal : Strideable {
    public func distance(to other: Decimal) -> Decimal {
        return self - other
    }
    public func advanced(by n: Decimal) -> Decimal {
        return self + n
    }
}

extension Decimal {
    public typealias RoundingMode = NSDecimalNumber.RoundingMode
    public typealias CalculationError = NSDecimalNumber.CalculationError
    public init(_ value: UInt8) {
        self.init(UInt64(value))
    }
    public init(_ value: Int8) {
        self.init(Int64(value))
    }
    public init(_ value: UInt16) {
        self.init(UInt64(value))
    }
    public init(_ value: Int16) {
        self.init(Int64(value))
    }
    public init(_ value: UInt32) {
        self.init(UInt64(value))
    }
    public init(_ value: Int32) {
        self.init(Int64(value))
    }
    public init(_ value: Double) {
        if value.isNaN {
            self = Decimal.nan
        } else if value == 0.0 {
            self = Decimal()
        } else {
            self = Decimal()
            let negative = value < 0
            var val = negative ? -1 * value : value
            var exponent = 0
            while val < Double(UInt64.max - 1) {
                val *= 10.0
                exponent -= 1
            }
            while Double(UInt64.max - 1) < val {
                val /= 10.0
                exponent += 1
            }
            var mantissa = UInt64(val)

            var i = Int32(0)
            // this is a bit ugly but it is the closest approximation of the C initializer that can be expressed here.
            while mantissa != 0 && i < NSDecimalMaxSize {
                switch i {
                case 0:
                    _mantissa.0 = UInt16(truncatingIfNeeded:mantissa)
                case 1:
                    _mantissa.1 = UInt16(truncatingIfNeeded:mantissa)
                case 2:
                    _mantissa.2 = UInt16(truncatingIfNeeded:mantissa)
                case 3:
                    _mantissa.3 = UInt16(truncatingIfNeeded:mantissa)
                case 4:
                    _mantissa.4 = UInt16(truncatingIfNeeded:mantissa)
                case 5:
                    _mantissa.5 = UInt16(truncatingIfNeeded:mantissa)
                case 6:
                    _mantissa.6 = UInt16(truncatingIfNeeded:mantissa)
                case 7:
                    _mantissa.7 = UInt16(truncatingIfNeeded:mantissa)
                default:
                    fatalError("initialization overflow")
                }
                mantissa = mantissa >> 16
                i += 1
            }
            _length = UInt32(i)
            _isNegative = negative ? 1 : 0
            _isCompact = 0
            _exponent = Int32(exponent)
            self.compact()
        }
    }
    public init(_ value: UInt64) {
        self.init(Double(value))
    }
    public init(_ value: Int64) {
        self.init(Double(value))
    }
    public init(_ value: UInt) {
        self.init(UInt64(value))
    }
    public init(_ value: Int) {
        self.init(Int64(value))
    }
    public var isSignalingNaN: Bool {
        return false
    }
    public static var nan: Decimal {
        return quietNaN
    }
    public static var quietNaN: Decimal {
        var quiet = Decimal()
        quiet._isNegative = 1
        return quiet
    }
    public var floatingPointClass: FloatingPointClassification {
        if _length == 0 && _isNegative == 1 {
            return .quietNaN
        } else if _length == 0 {
            return .positiveZero
        }
        if _isNegative == 1 {
            return .negativeNormal
        } else {
            return .positiveNormal
        }
    }
    public var isSignMinus: Bool {
        return _isNegative != 0
    }
    public var isNormal: Bool {
        return !isZero && !isInfinite && !isNaN
    }
    public var isFinite: Bool {
        return !isNaN
    }
    public var isZero: Bool {
        return _length == 0 && _isNegative == 0
    }
    public var isSubnormal: Bool {
        return false
    }
    public var isInfinite: Bool {
        return false
    }
    public var isNaN: Bool {
        return _length == 0 && _isNegative == 1
    }
    public var isSignaling: Bool {
        return false
    }
}

extension Decimal : CustomStringConvertible {
    public init?(string: String, locale: Locale? = nil) {
        let scan = Scanner(string: string)
        var theDecimal = Decimal()
        if !scan.scanDecimal(&theDecimal) {
            return nil
        }
        self = theDecimal
    }
    public var description: String {
        if self.isNaN {
            return "NaN"
        }
        if _length == 0 {
            return "0"
        }
        var copy = self
        let ZERO : CChar = 0x30 // ASCII '0' == 0x30
        let decimalChar : CChar = 0x2e // ASCII '.' == 0x2e
        let MINUS : CChar = 0x2d // ASCII '-' == 0x2d

        let bufferSize = 200 // max value : 39+128+sign+decimalpoint
        var buffer = Array<CChar>(repeating: 0, count: bufferSize)

        var i = bufferSize - 1
        while copy._exponent > 0 {
            i -= 1
            buffer[i] = ZERO
            copy._exponent -= 1
        }

        if copy._exponent == 0 {
            copy._exponent = 1
        }

        while copy._length != 0 {
            var remainder: UInt16 = 0
            if copy._exponent == 0 {
                i -= 1
                buffer[i] = decimalChar
            }
            copy._exponent += 1
            (remainder,_) = divideByShort(&copy, 10)
            i -= 1
            buffer[i] = Int8(remainder) + ZERO
        }
        if copy._exponent <= 0 {
            while copy._exponent != 0 {
                i -= 1
                buffer[i] = ZERO
                copy._exponent += 1
            }
            i -= 1
            buffer[i] = decimalChar
            i -= 1
            buffer[i] = ZERO
        }
        if copy._isNegative != 0 {
            i -= 1
            buffer[i] = MINUS
        }
        return String(cString: Array(buffer.suffix(from:i)))
    }
}

fileprivate func divideByShort<T:VariableLengthNumber>(_ d: inout T, _ divisor:UInt16) -> (UInt16,NSDecimalNumber.CalculationError) {
    if divisor == 0 {
        d._length = 0
        return (0,.divideByZero)
    }
    // note the below is not the same as from length to 0 by -1
    var carry: UInt32 = 0
    for i in (0..<d._length).reversed() {
        let accumulator = UInt32(d[i]) + carry * (1<<16)
        d[i] = UInt16(accumulator / UInt32(divisor))
        carry = accumulator % UInt32(divisor)
    }
    d.trimTrailingZeros()
    return (UInt16(carry),.noError)
}

fileprivate func multiplyByShort<T:VariableLengthNumber>(_ d: inout T, _ mul:UInt16) -> NSDecimalNumber.CalculationError {
    if mul == 0 {
        d._length = 0
        return .noError
    }
    var carry: UInt32 = 0
    // FIXME handle NSCalculationOverflow here?
    for i in 0..<d._length {
        let accumulator: UInt32 = UInt32(d[i]) * UInt32(mul) + carry
        carry = accumulator >> 16
        d[i] = UInt16(truncatingIfNeeded: accumulator)
    }
    if carry != 0 {
        if d._length >= Decimal.maxSize {
            return .overflow
        }
        d[d._length] = UInt16(truncatingIfNeeded: carry)
        d._length += 1
    }
    return .noError
}

fileprivate func addShort<T:VariableLengthNumber>(_ d: inout T, _ add:UInt16) -> NSDecimalNumber.CalculationError {
    var carry:UInt32 = UInt32(add)
    for i in 0..<d._length {
        let accumulator: UInt32 = UInt32(d[i]) + carry
        carry = accumulator >> 16
        d[i] = UInt16(truncatingIfNeeded: accumulator)
    }
    if carry != 0 {
        if d._length >= Decimal.maxSize {
            return .overflow
        }
        d[d._length] = UInt16(truncatingIfNeeded: carry)
        d._length += 1
    }
    return .noError
}

public func NSDecimalIsNotANumber(_ dcm: UnsafePointer<Decimal>) -> Bool {
	return dcm.pointee.isNaN
}

/***************	Operations		***********/
public func NSDecimalCopy(_ destination: UnsafeMutablePointer<Decimal>, _ source: UnsafePointer<Decimal>) {
    destination.pointee.__lengthAndFlags = source.pointee.__lengthAndFlags
    destination.pointee.__exponent = source.pointee.__exponent
    destination.pointee.__reserved = source.pointee.__reserved
    destination.pointee._mantissa = source.pointee._mantissa
}

public func NSDecimalCompact(_ number: UnsafeMutablePointer<Decimal>) {
    number.pointee.compact()
}

// NSDecimalCompare:Compares leftOperand and rightOperand.
public func NSDecimalCompare(_ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>) -> ComparisonResult {
    let left = leftOperand.pointee
    let right = rightOperand.pointee
    return left.compare(to: right)
}

fileprivate extension UInt16 {
    func compareTo(_ other: UInt16) -> ComparisonResult {
        if self < other {
            return .orderedAscending
        } else if self > other {
            return .orderedDescending
        } else {
            return .orderedSame
        }
    }
}

fileprivate func mantissaCompare<T:VariableLengthNumber>(
    _ left: T,
    _ right: T) -> ComparisonResult {

    if left._length > right._length {
        return .orderedDescending
    }
    if left._length < right._length {
        return .orderedAscending
    }
    let length = left._length // == right._length
    for i in (0..<length).reversed() {
        let comparison = left[i].compareTo(right[i])
        if comparison != .orderedSame {
            return comparison
        }
    }
    return .orderedSame
}

fileprivate func fitMantissa(_ big: inout WideDecimal, _ exponent: inout Int32, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {

    if big._length <= Decimal.maxSize {
        return .noError
    }

    var remainder: UInt16 = 0
    var previousRemainder: Bool = false

    // Divide by 10 as much as possible
    while big._length > Decimal.maxSize + 1 {
        if remainder != 0 {
            previousRemainder = true
        }
        (remainder,_) = divideByShort(&big,10000)
        exponent += 4
    }

    while big._length > Decimal.maxSize {
        if remainder != 0 {
            previousRemainder = true
        }
        (remainder,_) = divideByShort(&big,10)
        exponent += 1
    }

    // If we are on a tie, adjust with previous remainder.
    // .50001 is equivalent to .6
    if previousRemainder && (remainder == 0 || remainder == 5) {
        remainder += 1
    }

    if remainder == 0 {
        return .noError
    }

    // Round the result
    switch roundingMode  {
    case .down:
        break
    case .bankers:
        if remainder == 5 && (big[0] & 1) == 0 {
            break
        }
        fallthrough
    case .plain:
        if remainder < 5 {
            break
        }
        fallthrough
    case .up:
        let originalLength = big._length
        // big._length += 1 ??
        _ = addShort(&big,1)
        if originalLength > big._length {
            // the last digit is == 0. Remove it.
            _ = divideByShort(&big, 10)
            exponent += 1
        }
    }
    return .lossOfPrecision;
}

fileprivate func integerMultiply<T:VariableLengthNumber>(_ big: inout T,
                                 _ left: T,
                                 _ right: Decimal) -> NSDecimalNumber.CalculationError {
    if left._length == 0 || right._length == 0 {
        big._length = 0
        return .noError
    }

    if big._length == 0 || big._length > left._length + right._length {
        big._length = min(big.maxMantissaLength,left._length + right._length)
    }

    big.zeroMantissa()

    var carry: UInt16 = 0

    for j in 0..<right._length {
        var accumulator: UInt32 = 0
        carry = 0

        for i in 0..<left._length {
            if i + j < big._length {
                let bigij = UInt32(big[i+j])
                accumulator = UInt32(carry) + bigij + UInt32(right[j]) * UInt32(left[i])
                carry = UInt16(truncatingIfNeeded:accumulator >> 16)
                big[i+j] = UInt16(truncatingIfNeeded:accumulator)
            } else if carry != 0 || (right[j] == 0 && left[j] == 0) {
                return .overflow
            }
        }

        if carry != 0 {
            if left._length + j < big._length {
                big[left._length + j] = carry
            } else {
                return .overflow
            }
        }
    }

    big.trimTrailingZeros()

    return .noError
}

fileprivate func integerDivide<T:VariableLengthNumber>(_ r: inout T,
                               _ cu: T,
                               _ cv: Decimal) -> NSDecimalNumber.CalculationError {
    // Calculate result = a / b.
    // Result could NOT be a pointer to same space as a or b.
    // resultLen must be >= aLen - bLen.
    //
    // Based on algorithm in The Art of Computer Programming, Volume 2,
    // Seminumerical Algorithms by Donald E. Knuth, 2nd Edition. In addition
    // you need to consult the erratas for the book available at:
    //
    //   http://www-cs-faculty.stanford.edu/~uno/taocp.html

    var u = WideDecimal(true)
    var v = WideDecimal(true) // divisor

    // Simple case
    if cv.isZero {
        return .divideByZero;
    }

    // If u < v, the result is approximately 0...
    if cu._length < cv._length {
        for i in 0..<cv._length {
            if cu[i] < cv[i] {
                r._length = 0
                return .noError;
            }
        }
    }

    // Fast algorithm
    if cv._length == 1 {
        r = cu
        let (_,error) = divideByShort(&r, cv[0])
        return error
    }

    u.copyMantissa(from: cu)
    v.copyMantissa(from: cv)

    u._length = cu._length + 1
    v._length = cv._length + 1

    // D1: Normalize
    // Calculate d such that d*highest_digit of v >= b/2 (0x8000)
    //
    // I could probably use something smarter to get d to be a power of 2.
    // In this case the multiply below became only a shift.
    let d: UInt32 = UInt32((1 << 16) / Int(cv[cv._length - 1] + 1))

    // This is to make the whole algorithm work and u*d/v*d == u/v
    _ = multiplyByShort(&u, UInt16(d))
    _ = multiplyByShort(&v, UInt16(d))

    u.trimTrailingZeros()
    v.trimTrailingZeros()

    // Set a zero at the leftmost u position if the multiplication
    // does not have a carry.
    if u._length == cu._length {
        u[u._length] = 0
        u._length += 1
    }

    v[v._length] = 0; // Set a zero at the leftmost v position.
    // the algorithm will use it during the
    // multiplication/subtraction phase.

    // Determine the size of the quotient.
    // It's an approximate value.
    let ql:UInt16 = UInt16(u._length - v._length)

    // Some useful constants for the loop
    // It's used to determine the quotient digit as fast as possible
    // The test vl > 1 is probably useless, since optimizations
    // up there are taking over this case. I'll keep it, just in case.
    let v1:UInt16 = v[v._length-1]
    let v2:UInt16 = v._length > 1 ? v[v._length-2] : 0

    // D2: initialize j
    // On each pass, build a single value for the quotient.
    for j in 0..<ql {

        // D3: calculate q^
        // This formula and test for q gives at most q+1; See Knuth for proof.

        let ul = u._length
        let tmp:UInt32 = UInt32(u[ul - UInt32(j) - UInt32(1)]) << 16 + UInt32(u[ul - UInt32(j) - UInt32(2)])
        var q:UInt32 = tmp / UInt32(v1) // Quotient digit. could be a short.
        var rtmp:UInt32 = tmp % UInt32(v1)

        // This test catches all cases where q is really q+2 and
        // most where it is q+1
        if q == (1 << 16) || UInt32(v2) * q > (rtmp<<16) + UInt32(u[ul - UInt32(j) - UInt32(3)]) {
            q -= 1
            rtmp += UInt32(v1)

            if (rtmp < (1 << 16)) && ( (q == (1 << 16) ) || ( UInt32(v2) * q > (rtmp<<16) + UInt32(u[ul - UInt32(j) - UInt32(3)])) ) {
                q -= 1
                rtmp += UInt32(v1)
            }
        }

        // D4: multiply and subtract.

        var mk:UInt32 = 0 // multiply carry
        var sk:UInt32 = 1 // subtraction carry
        var acc:UInt32

        // We perform a multiplication and a subtraction
        // during the same pass...
        for i in 0...v._length {
            let ul = u._length
            let vl = v._length
            acc = q * UInt32(v[i]) + mk     // multiply
            mk = acc >> 16                  // multiplication carry
            acc = acc & 0xffff;
            acc = 0xffff + UInt32(u[ul - vl + i - UInt32(j) - UInt32(1)]) - acc + sk; // subtract
            sk = acc >> 16;
            u[ul - vl + i - UInt32(j) - UInt32(1)] = UInt16(truncatingIfNeeded:acc)
        }

        // D5: test remainder
        // This test catches cases where q is still q + 1
        if sk == 0 {
            // D6: add back.
            var k:UInt32 = 0 // Addition carry

            // subtract one from the quotient digit
            q -= 1
            for i in 0...v._length {
                let ul = u._length
                let vl = v._length
                acc = UInt32(v[i]) + UInt32(u[UInt32(ul) - UInt32(vl) + UInt32(i) - UInt32(j) - UInt32(1)]) + k
                k = acc >> 16;
                u[UInt32(ul) - UInt32(vl) + UInt32(i) - UInt32(j) - UInt32(1)] = UInt16(truncatingIfNeeded:acc)
            }
            // k must be == 1 here
        }

        r[UInt32(ql - j - UInt16(1))] = UInt16(q)
        // D7: loop on j
    }

    r._length = UInt32(ql);

    r.trimTrailingZeros()

    return .noError;
}

fileprivate func integerMultiplyByPowerOf10<T:VariableLengthNumber>(_ result: inout T, _ left: T, _ p: Int) -> NSDecimalNumber.CalculationError {
    var power = p
    if power == 0 {
        result = left
        return .noError
    }
    let isNegative = power < 0
    if isNegative {
        power = -power
    }
    result = left

    let maxpow10 = pow10.count - 1
    var error:NSDecimalNumber.CalculationError = .noError

    while power > maxpow10 {
        var big = T()

        power -= maxpow10
        let p10 = pow10[maxpow10]

        if !isNegative {
            error = integerMultiply(&big,result,p10)
        } else {
            error = integerDivide(&big,result,p10)
        }

        if error != .noError && error != .lossOfPrecision {
            return error;
        }

        for i in 0..<big._length {
            result[i] = big[i]
        }

        result._length = big._length
    }

    var big = T()

    // Handle the rest of the power (<= maxpow10)
    let p10 = pow10[Int(power)]

    if !isNegative {
        error = integerMultiply(&big, result, p10)
    } else {
        error = integerDivide(&big, result, p10)
    }

    for i in 0..<big._length {
        result[i] = big[i]
    }

    result._length = big._length

    return error;
}

public func NSDecimalRound(_ result: UnsafeMutablePointer<Decimal>, _ number: UnsafePointer<Decimal>, _ scale: Int, _ roundingMode: NSDecimalNumber.RoundingMode) {
    NSDecimalCopy(result,number) // this is unnecessary if they are the same address, but we can't test that here
    result.pointee.round(scale: scale,roundingMode: roundingMode)
}
// Rounds num to the given scale using the given mode.
// result may be a pointer to same space as num.
// scale indicates number of significant digits after the decimal point

public func NSDecimalNormalize(_ a: UnsafeMutablePointer<Decimal>, _ b: UnsafeMutablePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
    var diffexp = a.pointee.__exponent - b.pointee.__exponent
    var result = Decimal()

    //
    // If the two numbers share the same exponents,
    // the normalisation is already done
    //
    if diffexp == 0 {
        return .noError
    }

    //
    // Put the smallest of the two in aa
    //
    var aa: UnsafeMutablePointer<Decimal>
    var bb: UnsafeMutablePointer<Decimal>

    if diffexp < 0 {
        aa = b
        bb = a
        diffexp = -diffexp
    } else {
        aa = a
        bb = b
    }

    //
    // Build a backup for aa
    //
    var backup = Decimal()

    NSDecimalCopy(&backup,aa)

    //
    // Try to multiply aa to reach the same exponent level than bb
    //

    if integerMultiplyByPowerOf10(&result, aa.pointee, Int(diffexp)) == .noError {
        // Succeed. Adjust the length/exponent info
        // and return no errorNSDecimalNormalize
        aa.pointee.copyMantissa(from: result)
        aa.pointee._exponent = bb.pointee._exponent
        return .noError;
    }

    //
    // Failed, restart from scratch
    //
    NSDecimalCopy(aa, &backup);

    //
    // What is the maximum pow10 we can apply to aa ?
    //
    let logBase10of2to16 = 4.81647993
    let aaLength = aa.pointee._length
    let maxpow10 = Int8(floor(Double(Decimal.maxSize - aaLength) * logBase10of2to16))

    //
    // Divide bb by this value
    //
    _ = integerMultiplyByPowerOf10(&result, bb.pointee, Int(maxpow10 - diffexp))

    bb.pointee.copyMantissa(from: result)
    bb.pointee._exponent -= Int32(maxpow10 - diffexp);

    //
    // If bb > 0 multiply aa by the same value
    //
    if !bb.pointee.isZero {
        _ = integerMultiplyByPowerOf10(&result, aa.pointee, Int(maxpow10))
        aa.pointee.copyMantissa(from: result)
        aa.pointee._exponent -= Int32(maxpow10)
    } else {
        bb.pointee._exponent = aa.pointee._exponent;
    }

    //
    // the two exponents are now identical, but we've lost some digits in the operation.
    //
    return .lossOfPrecision;
}

public func NSDecimalAdd(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
    if leftOperand.pointee.isNaN || rightOperand.pointee.isNaN {
        result.pointee.setNaN()
        return .overflow
    }
    if leftOperand.pointee.isZero {
        NSDecimalCopy(result, rightOperand)
        return .noError
    } else if rightOperand.pointee.isZero {
        NSDecimalCopy(result, leftOperand)
        return .noError
    } else {
        var a = Decimal()
        var b = Decimal()
        var error:NSDecimalNumber.CalculationError = .noError

        NSDecimalCopy(&a,leftOperand)
        NSDecimalCopy(&b,rightOperand)

        let normalizeError = NSDecimalNormalize(&a, &b,roundingMode)

        if a.isZero {
            NSDecimalCopy(result,&b)
            return normalizeError
        }
        if b.isZero {
            NSDecimalCopy(result,&a)
            return normalizeError
        }

        result.pointee._exponent = a._exponent

        if a.isNegative == b.isNegative {
            var big = WideDecimal()
            result.pointee.isNegative = a.isNegative

            // No possible error here.
            _ = integerAdd(&big,&a,&b)

            if big._length > Decimal.maxSize {
                var exponent:Int32 = 0
                error = fitMantissa(&big, &exponent, roundingMode)

                let newExponent = result.pointee._exponent + exponent

                // Just to be sure!
                if newExponent > Int32(Int8.max) {
                    result.pointee.setNaN()
                    return .overflow
                }
                result.pointee._exponent = newExponent
            }
            let length = min(Decimal.maxSize,big._length)
            for i in 0..<length {
                result.pointee[i] = big[i]
            }
            result.pointee._length = length
        } else { // not the same sign
            let comparison = mantissaCompare(a,b)

            switch comparison {
            case .orderedSame:
                result.pointee.setZero()
            case .orderedAscending:
                _ = integerSubtract(&result.pointee,&b,&a)
                result.pointee.isNegative = b.isNegative
            case .orderedDescending:
                _ = integerSubtract(&result.pointee,&a,&b)
                result.pointee.isNegative = a.isNegative
            }
        }
        result.pointee._isCompact = 0
        NSDecimalCompact(result)
        return error == .noError ? normalizeError : error
    }
}

fileprivate func integerAdd(_ result: inout WideDecimal, _ left: inout Decimal, _ right: inout Decimal) -> NSDecimalNumber.CalculationError {
    var i:UInt32 = 0
    var carry:UInt16 = 0
    var accumulator:UInt32 = 0

    let c:UInt32 = min(left._length, right._length)

    while i < c {
        let li = UInt32(left[i])
        let ri = UInt32(right[i])
        accumulator = li + ri + UInt32(carry)
        carry = UInt16(truncatingIfNeeded:accumulator >> 16)
        result[i] = UInt16(truncatingIfNeeded:accumulator)
        i += 1
    }

    while i < left._length {
        if carry != 0 {
            let li = UInt32(left[i])
            accumulator = li + UInt32(carry)
            carry = UInt16(truncatingIfNeeded:accumulator >> 16)
            result[i] = UInt16(truncatingIfNeeded:accumulator)
            i += 1
        } else {
            while i < left._length {
                result[i] = left[i]
                i += 1
            }
            break
        }
    }
    while i < right._length {
        if carry != 0 {
            let ri = UInt32(right[i])
            accumulator = ri + UInt32(carry)
            carry = UInt16(truncatingIfNeeded:accumulator >> 16)
            result[i] = UInt16(truncatingIfNeeded:accumulator)
            i += 1
        } else {
            while i < right._length {
                result[i] = right[i]
                i += 1
            }
            break
        }
    }

    if carry != 0 {
        if result._length < i {
            result._length = i
            return .overflow
        } else {
            result[i] = carry
            i += 1
        }
    }
    result._length = i;
    return .noError;
}

// integerSubtract: Subtract b from a, put the result in result, and
//     modify resultLen to match the length of the result.
// Result may be a pointer to same space as a or b.
// resultLen must be >= Max(aLen,bLen).
// Could return NSCalculationOverflow if b > a. In this case 0 - result
//    give b-a...
//
fileprivate func integerSubtract(_ result: inout Decimal, _ left: inout Decimal, _ right: inout Decimal) -> NSDecimalNumber.CalculationError {
    var i:UInt32 = 0
    var carry:UInt16 = 1
    var accumulator:UInt32 = 0

    let c:UInt32 = min(left._length, right._length)

    while i < c {
        let li = UInt32(left[i])
        let ri = UInt32(right[i])
        accumulator = 0xffff + li - ri + UInt32(carry)
        carry = UInt16(truncatingIfNeeded:accumulator >> 16)
        result[i] = UInt16(truncatingIfNeeded:accumulator)
        i += 1
    }

    while i < left._length {
        if carry != 0 {
            let li = UInt32(left[i])
            accumulator = 0xffff + li // + no carry
            carry = UInt16(truncatingIfNeeded:accumulator >> 16)
            result[i] = UInt16(truncatingIfNeeded:accumulator)
            i += 1
        } else {
            while i < left._length {
                result[i] = left[i]
                i += 1
            }
            break
        }
    }
    while i < right._length {
        let ri = UInt32(right[i])
        accumulator = 0xffff - ri + UInt32(carry)
        carry = UInt16(truncatingIfNeeded:accumulator >> 16)
        result[i] = UInt16(truncatingIfNeeded:accumulator)
        i += 1
    }

    if carry != 0 {
        return .overflow
    }
    result._length = i;

    result.trimTrailingZeros()

    return .noError;
}

// Exact operations. result may be a pointer to same space as leftOperand or rightOperand

public func NSDecimalSubtract(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
    var r = rightOperand.pointee
    r.negate()
    return NSDecimalAdd(result, leftOperand, &r, roundingMode)
}
// Exact operations. result may be a pointer to same space as leftOperand or rightOperand

public func NSDecimalMultiply(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {

    if leftOperand.pointee.isNaN || rightOperand.pointee.isNaN {
        result.pointee.setNaN()
        return .overflow
    }
    if leftOperand.pointee.isZero || rightOperand.pointee.isZero {
        result.pointee.setZero()
        return .noError
    }

    var big = WideDecimal()
    var calculationError:NSDecimalNumber.CalculationError = .noError

    calculationError = integerMultiply(&big,WideDecimal(leftOperand.pointee),rightOperand.pointee)

    result.pointee._isNegative = (leftOperand.pointee._isNegative + rightOperand.pointee._isNegative) % 2

    var newExponent = leftOperand.pointee._exponent + rightOperand.pointee._exponent

    if big._length > Decimal.maxSize {
        var exponent:Int32 = 0
        calculationError = fitMantissa(&big, &exponent, roundingMode)
        newExponent += exponent
    }

    for i in 0..<big._length {
       result.pointee[i] = big[i]
    }
    result.pointee._length = big._length
    result.pointee._isCompact = 0

    if newExponent > Int32(Int8.max) {
        result.pointee.setNaN()
        return .overflow
    }
    result.pointee._exponent = newExponent
    NSDecimalCompact(result)
    return calculationError
}
// Exact operations. result may be a pointer to same space as leftOperand or rightOperand

public func NSDecimalDivide(_ result: UnsafeMutablePointer<Decimal>, _ leftOperand: UnsafePointer<Decimal>, _ rightOperand: UnsafePointer<Decimal>, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {

    if leftOperand.pointee.isNaN || rightOperand.pointee.isNaN {
        result.pointee.setNaN()
        return .overflow
    }
    if rightOperand.pointee.isZero {
        result.pointee.setNaN()
        return .divideByZero
    }
    if leftOperand.pointee.isZero {
        result.pointee.setZero()
        return .noError
    }
    var a = Decimal()
    var b = Decimal()
    var big = WideDecimal()
    var exponent:Int32 = 0

    NSDecimalCopy(&a, leftOperand)
    NSDecimalCopy(&b, rightOperand)

    /* If the precision of the left operand is much smaller
     * than that of the right operand (for example,
     * 20 and 0.112314123094856724234234572), then the
     * difference in their exponents is large and a lot of
     * precision will be lost below. This is particularly
     * true as the difference approaches 38 or larger.
     * Normalizing here looses some precision on the
     * individual operands, but often produces a more
     * accurate result later. I chose 19 arbitrarily
     * as half of the magic 38, so that normalization
     * doesn't always occur. */
    if (19 <= Int(a._exponent - b._exponent)) {
        _ = NSDecimalNormalize(&a, &b, roundingMode);
        /* We ignore the small loss of precision this may
         * induce in the individual operands. */

        /* Sometimes the normalization done previously is inappropriate and
         * forces one of the operands to 0. If this happens, restore both. */
        if a.isZero || b.isZero {
            NSDecimalCopy(&a, leftOperand);
            NSDecimalCopy(&b, rightOperand);
        }
    }

    _ = integerMultiplyByPowerOf10(&big, WideDecimal(a), 38) // Trust me, it's 38 !
    _ = integerDivide(&big, big, b)
    _ = fitMantissa(&big, &exponent, .down)

    let length = min(big._length,Decimal.maxSize)
    for i in 0..<length {
        result.pointee[i] = big[i]
    }

    result.pointee._length = length

    result.pointee.isNegative = a._isNegative != b._isNegative

    exponent = a._exponent - b._exponent - 38 + exponent
    if exponent < Int32(Int8.min) {
        result.pointee.setNaN()
        return .underflow
    }
    if exponent > Int32(Int8.max) {
        result.pointee.setNaN()
        return .overflow;
    }
    result.pointee._exponent = Int32(exponent)
    result.pointee._isCompact = 0
    NSDecimalCompact(result)
    return .noError
}
// Division could be silently inexact;
// Exact operations. result may be a pointer to same space as leftOperand or rightOperand

public func NSDecimalPower(_ result: UnsafeMutablePointer<Decimal>, _ number: UnsafePointer<Decimal>, _ power: Int, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {

    if number.pointee.isNaN {
        result.pointee.setNaN()
        return .overflow
    }
    NSDecimalCopy(result,number)
    return result.pointee.power(UInt(power), roundingMode:roundingMode)
}

public func NSDecimalMultiplyByPowerOf10(_ result: UnsafeMutablePointer<Decimal>, _ number: UnsafePointer<Decimal>, _ power: Int16, _ roundingMode: NSDecimalNumber.RoundingMode) -> NSDecimalNumber.CalculationError {
    NSDecimalCopy(result,number)
    return result.pointee.multiply(byPowerOf10: power)
}

public func NSDecimalString(_ dcm: UnsafePointer<Decimal>, _ locale: Any?) -> String {
    guard locale == nil else {
        fatalError("Locale not supported: \(locale!)")
    }
    return dcm.pointee.description
}

private func multiplyBy10(_ dcm: inout Decimal, andAdd extra:Int) -> NSDecimalNumber.CalculationError {
    let backup = dcm

    if multiplyByShort(&dcm, 10) == .noError && addShort(&dcm, UInt16(extra)) == .noError {
        return .noError
    } else {
        dcm = backup // restore the old values
        return .overflow // this is the only possible error
    }
}

fileprivate protocol VariableLengthNumber {
    var _length: UInt32 { get set }
    init()
    subscript(index:UInt32) -> UInt16 { get set }
    var isZero:Bool { get }
    mutating func copyMantissa<T:VariableLengthNumber>(from other:T)
    mutating func zeroMantissa()
    mutating func trimTrailingZeros()
    var maxMantissaLength: UInt32 { get }
}

extension Decimal: VariableLengthNumber {
    var maxMantissaLength:UInt32 {
        return Decimal.maxSize
    }
    fileprivate mutating func zeroMantissa() {
        for i in 0..<Decimal.maxSize {
            self[i] = 0
        }
    }
    internal mutating func trimTrailingZeros() {
        if _length > Decimal.maxSize {
            _length = Decimal.maxSize
        }
        while _length != 0 && self[_length - 1] == 0 {
            _length -= 1
        }
    }
    fileprivate mutating func copyMantissa<T : VariableLengthNumber>(from other: T) {
        if other._length > maxMantissaLength {
            for i in maxMantissaLength..<other._length {
                guard other[i] == 0 else {
                    fatalError("Loss of precision during copy other[\(i)] \(other[i]) != 0")
                }
            }
        }
        let length = min(other._length, maxMantissaLength)
        for i in 0..<length {
            self[i] = other[i]
        }
        self._length = length
        self._isCompact = 0
    }
}

// Provides a way with dealing with extra-length decimals, used for calculations
fileprivate struct WideDecimal : VariableLengthNumber {
    var maxMantissaLength:UInt32 {
        return _extraWide ? 17 : 16
    }

    fileprivate mutating func zeroMantissa() {
        for i in 0..<maxMantissaLength {
            self[i] = 0
        }
    }
    fileprivate mutating func trimTrailingZeros() {
        while _length != 0 && self[_length - 1] == 0 {
            _length -= 1
        }
    }
    init() {
        self.init(false)
    }

    fileprivate mutating func copyMantissa<T : VariableLengthNumber>(from other: T) {
        let length = other is Decimal ? min(other._length,Decimal.maxSize) : other._length
        for i in 0..<length {
            self[i] = other[i]
        }
        self._length = length
    }

    var isZero: Bool {
        return _length == 0
    }

    var __length: UInt16
    var _mantissa: (UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16,
        UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16, UInt16)
    // Most uses of this class use 16 shorts, but integer division uses 17 shorts
    var _extraWide: Bool
    var _length: UInt32 {
        get {
            return UInt32(__length)
        }
        set {
            guard newValue <= maxMantissaLength else {
                fatalError("Attempt to set a length greater than capacity \(newValue) > \(maxMantissaLength)")
            }
            __length = UInt16(newValue)
        }
    }
    init(_ extraWide:Bool = false) {
        __length = 0
        _mantissa = (UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0))
        _extraWide = extraWide
    }
    init(_ decimal:Decimal) {
        self.__length = UInt16(decimal._length)
        self._extraWide = false
        self._mantissa = (decimal[0],decimal[1],decimal[2],decimal[3],decimal[4],decimal[5],decimal[6],decimal[7],UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0),UInt16(0))
    }
    subscript(index:UInt32) -> UInt16 {
        get {
            switch index {
            case 0: return _mantissa.0
            case 1: return _mantissa.1
            case 2: return _mantissa.2
            case 3: return _mantissa.3
            case 4: return _mantissa.4
            case 5: return _mantissa.5
            case 6: return _mantissa.6
            case 7: return _mantissa.7
            case 8: return _mantissa.8
            case 9: return _mantissa.9
            case 10: return _mantissa.10
            case 11: return _mantissa.11
            case 12: return _mantissa.12
            case 13: return _mantissa.13
            case 14: return _mantissa.14
            case 15: return _mantissa.15
            case 16 where _extraWide: return _mantissa.16 // used in integerDivide
            default: fatalError("Invalid index \(index) for _mantissa")
            }
        }
        set {
            switch index {
            case 0: _mantissa.0 = newValue
            case 1: _mantissa.1 = newValue
            case 2: _mantissa.2 = newValue
            case 3: _mantissa.3 = newValue
            case 4: _mantissa.4 = newValue
            case 5: _mantissa.5 = newValue
            case 6: _mantissa.6 = newValue
            case 7: _mantissa.7 = newValue
            case 8: _mantissa.8 = newValue
            case 9: _mantissa.9 = newValue
            case 10: _mantissa.10 = newValue
            case 11: _mantissa.11 = newValue
            case 12: _mantissa.12 = newValue
            case 13: _mantissa.13 = newValue
            case 14: _mantissa.14 = newValue
            case 15: _mantissa.15 = newValue
            case 16 where _extraWide: _mantissa.16 = newValue
            default: fatalError("Invalid index \(index) for _mantissa")
            }
        }
    }
    func toDecimal() -> Decimal {
        var result = Decimal()
        result._length = self._length
        for i in 0..<_length {
            result[i] = self[i]
        }
        return result
    }
}

// == Internal (Swifty) functions ==

extension Decimal {
    fileprivate var isCompact: Bool {
        get {
            return _isCompact != 0
        }
        set {
            _isCompact = newValue ? 1 : 0
        }
    }
    fileprivate var isNegative: Bool {
        get {
            return _isNegative != 0
        }
        set {
            _isNegative = newValue ? 1 : 0
        }
    }
    fileprivate mutating func compact() {
        if isCompact || isNaN || _length == 0 {
            return
        }
        var newExponent = self._exponent
        var remainder: UInt16 = 0
        // Divide by 10 as much as possible
        repeat {
            (remainder,_) = divideByShort(&self,10)
            newExponent += 1
        } while remainder == 0
        // Put the non-empty remainder in place
        _ = multiplyByShort(&self,10)
        _ = addShort(&self,remainder)
        newExponent -= 1
        // Set the new exponent
        while newExponent > Int32(Int8.max) {
            _ = multiplyByShort(&self,10)
            newExponent -= 1
        }
        _exponent = newExponent
        isCompact = true
    }
    fileprivate mutating func round(scale:Int, roundingMode:RoundingMode) {
        // scale is the number of digits after the decimal point
        var s = Int32(scale) + _exponent
        if s == NSDecimalNoScale || s >= 0 {
            return
        }
        s = -s
        var remainder: UInt16 = 0
        var previousRemainder = false

        let negative = _isNegative != 0
        var newExponent = _exponent + s
        while s > 4 {
            if remainder != 0 {
                previousRemainder = true
            }
            (remainder,_) = divideByShort(&self, 10000)
            s -= 4
        }
        while s > 0 {
            if remainder != 0 {
                previousRemainder = true
            }
            (remainder,_) = divideByShort(&self, 10)
            s -= 1
        }
        // If we are on a tie, adjust with premdr. .50001 is equivalent to .6
        if previousRemainder && (remainder == 0 || remainder == 5) {
            remainder += 1;
        }
        if remainder != 0 {
            if negative {
                switch roundingMode {
                case .up:
                    break
                case .bankers:
                    if remainder == 5 && (self[0] & 1) == 0 {
                        remainder += 1
                    }
                    fallthrough
                case .plain:
                    if remainder < 5 {
                        break
                    }
                    fallthrough
                case .down:
                    _ = addShort(&self, 1)
                }
                if _length == 0 {
                    _isNegative = 0;
                }
            } else {
                switch roundingMode {
                case .down:
                    break
                case .bankers:
                    if remainder == 5 && (self[0] & 1) == 0 {
                        remainder -= 1
                    }
                    fallthrough
                case .plain:
                    if remainder < 5 {
                        break
                    }
                    fallthrough
                case .up:
                    _ = addShort(&self, 1)
                }
            }
        }
        _isCompact = 0;
        
        while newExponent > Int32(Int8.max) {
            newExponent -= 1;
            _ = multiplyByShort(&self, 10);
        }
        _exponent = newExponent;
        self.compact();
    }
    internal func compare(to other:Decimal) -> ComparisonResult {
        // NaN is a special case and is arbitrary ordered before everything else
        // Conceptually comparing with NaN is bogus anyway but raising or
        // always returning the same answer will confuse the sorting algorithms
        if self.isNaN {
            return other.isNaN ? .orderedSame : .orderedAscending
        }
        if other.isNaN {
            return .orderedDescending
        }
        // Check the sign
        if self._isNegative > other._isNegative {
            return .orderedAscending
        }
        if self._isNegative < other._isNegative {
            return .orderedDescending
        }
        // If one of the two is == 0, the other is bigger
        // because 0 implies isNegative = 0...
        if self.isZero && other.isZero {
            return .orderedSame
        }
        if self.isZero {
            return .orderedAscending
        }
        if other.isZero {
            return .orderedDescending
        }
        var selfNormal = self
        var otherNormal = other
        _ = NSDecimalNormalize(&selfNormal, &otherNormal, .down)
        let comparison = mantissaCompare(selfNormal,otherNormal)
        if selfNormal._isNegative == 1 {
            if comparison == .orderedDescending {
                return .orderedAscending
            } else if comparison == .orderedAscending {
                return .orderedDescending
            } else {
                return .orderedSame
            }
        }
        return comparison
    }
    fileprivate subscript(index:UInt32) -> UInt16 {
        get {
            switch index {
            case 0: return _mantissa.0
            case 1: return _mantissa.1
            case 2: return _mantissa.2
            case 3: return _mantissa.3
            case 4: return _mantissa.4
            case 5: return _mantissa.5
            case 6: return _mantissa.6
            case 7: return _mantissa.7
            default: fatalError("Invalid index \(index) for _mantissa")
            }
        }
        set {
            switch index {
            case 0: _mantissa.0 = newValue
            case 1: _mantissa.1 = newValue
            case 2: _mantissa.2 = newValue
            case 3: _mantissa.3 = newValue
            case 4: _mantissa.4 = newValue
            case 5: _mantissa.5 = newValue
            case 6: _mantissa.6 = newValue
            case 7: _mantissa.7 = newValue
            default: fatalError("Invalid index \(index) for _mantissa")
            }
        }
    }
    fileprivate mutating func setNaN() {
        _length = 0
        _isNegative = 1
    }
    fileprivate mutating func setZero() {
        _length = 0
        _isNegative = 0
    }
    fileprivate mutating func multiply(byPowerOf10 power:Int16) -> CalculationError {
        if isNaN {
            return .overflow
        }
        if isZero {
            return .noError
        }
        let newExponent = _exponent + Int32(power)
        if newExponent < Int32(Int8.min) {
            setNaN()
            return .underflow
        }
        if newExponent > Int32(Int8.max) {
            setNaN()
            return .overflow
        }
        _exponent = newExponent
        return .noError
    }
    fileprivate mutating func power(_ p:UInt, roundingMode:RoundingMode) -> CalculationError {
        if isNaN {
            return .overflow
        }
        var power = p
        if power == 0 {
            _exponent = 0
            _length = 1
            _isNegative = 0
            self[0] = 1
            _isCompact = 1
            return .noError
        } else if power == 1 {
            return .noError
        }

        var temporary = Decimal(1)
        var error:CalculationError = .noError

        while power > 1 {
            if power % 2 == 1 {
                let previousError = error
                var leftOp = temporary
                error = NSDecimalMultiply(&temporary, &leftOp, &self, roundingMode)

                if previousError != .noError { // FIXME is this the intent?
                    error = previousError
                }

                if error == .overflow || error == .underflow {
                    setNaN()
                    return error
                }
                power -= 1
            }
            if power != 0 {
                let previousError = error
                var leftOp = self
                var rightOp = self
                error = NSDecimalMultiply(&self, &leftOp, &rightOp, roundingMode)

                if previousError != .noError { // FIXME is this the intent?
                    error = previousError
                }

                if error == .overflow || error == .underflow {
                    setNaN()
                    return error
                }
                power /= 2
            }
        }
        let previousError = error
        var rightOp = self
        error = NSDecimalMultiply(&self, &temporary, &rightOp, roundingMode)

        if previousError != .noError { // FIXME is this the intent?
            error = previousError
        }

        if error == .overflow || error == .underflow {
            setNaN()
            return error
        }

        return error
    }
}

fileprivate let pow10 = [
/*^00*/ Decimal(length: 1, mantissa:( 0x0001,0,0,0,0,0,0,0)),
/*^01*/ Decimal(length: 1, mantissa:( 0x000a,0,0,0,0,0,0,0)),
/*^02*/ Decimal(length: 1, mantissa:( 0x0064,0,0,0,0,0,0,0)),
/*^03*/ Decimal(length: 1, mantissa:( 0x03e8,0,0,0,0,0,0,0)),
/*^04*/ Decimal(length: 1, mantissa:( 0x2710,0,0,0,0,0,0,0)),
/*^05*/ Decimal(length: 2, mantissa:( 0x86a0, 0x0001,0,0,0,0,0,0)),
/*^06*/ Decimal(length: 2, mantissa:( 0x4240, 0x000f,0,0,0,0,0,0)),
/*^07*/ Decimal(length: 2, mantissa:( 0x9680, 0x0098,0,0,0,0,0,0)),
/*^08*/ Decimal(length: 2, mantissa:( 0xe100, 0x05f5,0,0,0,0,0,0)),
/*^09*/ Decimal(length: 2, mantissa:( 0xca00, 0x3b9a,0,0,0,0,0,0)),
/*^10*/ Decimal(length: 3, mantissa:( 0xe400, 0x540b, 0x0002,0,0,0,0,0)),
/*^11*/ Decimal(length: 3, mantissa:( 0xe800, 0x4876, 0x0017,0,0,0,0,0)),
/*^12*/ Decimal(length: 3, mantissa:( 0x1000, 0xd4a5, 0x00e8,0,0,0,0,0)),
/*^13*/ Decimal(length: 3, mantissa:( 0xa000, 0x4e72, 0x0918,0,0,0,0,0)),
/*^14*/ Decimal(length: 3, mantissa:( 0x4000, 0x107a, 0x5af3,0,0,0,0,0)),
/*^15*/ Decimal(length: 4, mantissa:( 0x8000, 0xa4c6, 0x8d7e, 0x0003,0,0,0,0)),
/*^16*/ Decimal(length: 4, mantissa:( 0x0000, 0x6fc1, 0x86f2, 0x0023,0,0,0,0)),
/*^17*/ Decimal(length: 4, mantissa:( 0x0000, 0x5d8a, 0x4578, 0x0163,0,0,0,0)),
/*^18*/ Decimal(length: 4, mantissa:( 0x0000, 0xa764, 0xb6b3, 0x0de0,0,0,0,0)),
/*^19*/ Decimal(length: 4, mantissa:( 0x0000, 0x89e8, 0x2304, 0x8ac7,0,0,0,0)),
/*^20*/ Decimal(length: 5, mantissa:( 0x0000, 0x6310, 0x5e2d, 0x6bc7, 0x0005,0,0,0)),
/*^21*/ Decimal(length: 5, mantissa:( 0x0000, 0xdea0, 0xadc5, 0x35c9, 0x0036,0,0,0)),
/*^22*/ Decimal(length: 5, mantissa:( 0x0000, 0xb240, 0xc9ba, 0x19e0, 0x021e,0,0,0)),
/*^23*/ Decimal(length: 5, mantissa:( 0x0000, 0xf680, 0xe14a, 0x02c7, 0x152d,0,0,0)),
/*^24*/ Decimal(length: 5, mantissa:( 0x0000, 0xa100, 0xcced, 0x1bce, 0xd3c2,0,0,0)),
/*^25*/ Decimal(length: 6, mantissa:( 0x0000, 0x4a00, 0x0148, 0x1614, 0x4595, 0x0008,0,0)),
/*^26*/ Decimal(length: 6, mantissa:( 0x0000, 0xe400, 0x0cd2, 0xdcc8, 0xb7d2, 0x0052,0,0)),
/*^27*/ Decimal(length: 6, mantissa:( 0x0000, 0xe800, 0x803c, 0x9fd0, 0x2e3c, 0x033b,0,0)),
/*^28*/ Decimal(length: 6, mantissa:( 0x0000, 0x1000, 0x0261, 0x3e25, 0xce5e, 0x204f,0,0)),
/*^29*/ Decimal(length: 7, mantissa:( 0x0000, 0xa000, 0x17ca, 0x6d72, 0x0fae, 0x431e, 0x0001,0)),
/*^30*/ Decimal(length: 7, mantissa:( 0x0000, 0x4000, 0xedea, 0x4674, 0x9cd0, 0x9f2c, 0x000c,0)),
/*^31*/ Decimal(length: 7, mantissa:( 0x0000, 0x8000, 0x4b26, 0xc091, 0x2022, 0x37be, 0x007e,0)),
/*^32*/ Decimal(length: 7, mantissa:( 0x0000, 0x0000, 0xef81, 0x85ac, 0x415b, 0x2d6d, 0x04ee,0)),
/*^33*/ Decimal(length: 7, mantissa:( 0x0000, 0x0000, 0x5b0a, 0x38c1, 0x8d93, 0xc644, 0x314d,0)),
/*^34*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x8e64, 0x378d, 0x87c0, 0xbead, 0xed09, 0x0001)),
/*^35*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x8fe8, 0x2b87, 0x4d82, 0x72c7, 0x4261, 0x0013)),
/*^36*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x9f10, 0xb34b, 0x0715, 0x7bc9, 0x97ce, 0x00c0)),
/*^37*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x36a0, 0x00f4, 0x46d9, 0xd5da, 0xee10, 0x0785)),
/*^38*/ Decimal(length: 8, mantissa:( 0x0000, 0x0000, 0x2240, 0x098a, 0xc47a, 0x5a86, 0x4ca8, 0x4b3b))
/*^39 is on 9 shorts. */
]

// Copied from Scanner.swift
private func decimalSep(_ locale: Locale?) -> String {
    if let loc = locale {
        if let sep = loc._bridgeToObjectiveC().object(forKey: .decimalSeparator) as? NSString {
            return sep._swiftObject
        }
        return "."
    } else {
        return decimalSep(Locale.current)
    }
}

// Copied from Scanner.swift
private func isADigit(_ ch: unichar) -> Bool {
    struct Local {
        static let set = CharacterSet.decimalDigits
    }
    return Local.set.contains(UnicodeScalar(ch)!)
}

// Copied from Scanner.swift
private func numericValue(_ ch: unichar) -> Int {
    if (ch >= unichar(unicodeScalarLiteral: "0") && ch <= unichar(unicodeScalarLiteral: "9")) {
        return Int(ch) - Int(unichar(unicodeScalarLiteral: "0"))
    } else {
        return __CFCharDigitValue(UniChar(ch))
    }
}

// Could be silently inexact for float and double.
extension Scanner {

    public func scanDecimal(_ dcm: inout Decimal) -> Bool {
        if let result = scanDecimal() {
            dcm = result
            return true
        } else {
            return false
        }

    }
    public func scanDecimal() -> Decimal? {

        var result = Decimal()

        let string = self._scanString
        let length = string.length
        var buf = _NSStringBuffer(string: string, start: self._scanLocation, end: length)

        let ds_chars = decimalSep(locale).utf16
        let ds = ds_chars[ds_chars.startIndex]
        buf.skip(_skipSet)
        var neg = false

        if buf.currentCharacter == unichar(unicodeScalarLiteral: "-") || buf.currentCharacter == unichar(unicodeScalarLiteral: "+") {
            neg = buf.currentCharacter == unichar(unicodeScalarLiteral: "-")
            buf.advance()
            buf.skip(_skipSet)
        }
        guard isADigit(buf.currentCharacter) else {
            return nil
        }

        var tooBig = false

        // build the mantissa
        repeat {
            let numeral = numericValue(buf.currentCharacter)
            if numeral == -1 {
                break
            }

            if tooBig || multiplyBy10(&result,andAdd:numeral) != .noError {
                tooBig = true
                if result._exponent == Int32(Int8.max) {
                    repeat {
                        buf.advance()
                    } while isADigit(buf.currentCharacter)
                    return Decimal.nan
                }
                result._exponent += 1
            }
            buf.advance()
        } while isADigit(buf.currentCharacter)

        // get the decimal point
        if buf.currentCharacter == ds {
            buf.advance()
            // continue to build the mantissa
            repeat {
                let numeral = numericValue(buf.currentCharacter)
                if numeral == -1 {
                    break
                }
                if tooBig || multiplyBy10(&result,andAdd:numeral) != .noError {
                    tooBig = true
                } else {
                    if result._exponent == Int32(Int8.min) {
                        repeat {
                            buf.advance()
                        } while isADigit(buf.currentCharacter)
                        return Decimal.nan
                    }
                    result._exponent -= 1
                }
                buf.advance()
            } while isADigit(buf.currentCharacter)
        }

        if buf.currentCharacter == unichar(unicodeScalarLiteral: "e") || buf.currentCharacter == unichar(unicodeScalarLiteral: "E") {
            var exponentIsNegative = false
            var exponent: Int32 = 0

            buf.advance()
            if buf.currentCharacter == unichar(unicodeScalarLiteral: "-") {
                exponentIsNegative = true
                buf.advance()
            } else if buf.currentCharacter == unichar(unicodeScalarLiteral: "+") {
                buf.advance()
            }

            repeat {
                let numeral = numericValue(buf.currentCharacter)
                if numeral == -1 {
                    break
                }
                exponent = 10 * exponent + Int32(numeral)
                guard exponent <= 2*Int32(Int8.max) else {
                    return Decimal.nan
                }

                buf.advance()
            } while isADigit(buf.currentCharacter)

            if exponentIsNegative {
                exponent = -exponent
            }
            exponent += result._exponent
            guard exponent >= Int32(Int8.min) && exponent <= Int32(Int8.max) else {
                return Decimal.nan
            }
            result._exponent = exponent
        }

        result.isNegative = neg

        // if we get to this point, and have NaN, then the input string was probably "-0"
        // or some variation on that, and normalize that to zero.
        if result.isNaN {
            result = Decimal(0)
        }

        result.compact()
        self._scanLocation = buf.location
        return result
    }
}

extension Decimal : Codable {
    private enum CodingKeys : Int, CodingKey {
        case exponent
        case length
        case isNegative
        case isCompact
        case mantissa
    }
    
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let exponent = try container.decode(CInt.self, forKey: .exponent)
        let length = try container.decode(CUnsignedInt.self, forKey: .length)
        let isNegative = try container.decode(Bool.self, forKey: .isNegative)
        let isCompact = try container.decode(Bool.self, forKey: .isCompact)
        
        var mantissaContainer = try container.nestedUnkeyedContainer(forKey: .mantissa)
        var mantissa: (CUnsignedShort, CUnsignedShort, CUnsignedShort, CUnsignedShort,
            CUnsignedShort, CUnsignedShort, CUnsignedShort, CUnsignedShort) = (0,0,0,0,0,0,0,0)
        mantissa.0 = try mantissaContainer.decode(CUnsignedShort.self)
        mantissa.1 = try mantissaContainer.decode(CUnsignedShort.self)
        mantissa.2 = try mantissaContainer.decode(CUnsignedShort.self)
        mantissa.3 = try mantissaContainer.decode(CUnsignedShort.self)
        mantissa.4 = try mantissaContainer.decode(CUnsignedShort.self)
        mantissa.5 = try mantissaContainer.decode(CUnsignedShort.self)
        mantissa.6 = try mantissaContainer.decode(CUnsignedShort.self)
        mantissa.7 = try mantissaContainer.decode(CUnsignedShort.self)
        
        self.init(_exponent: exponent,
                  _length: length,
                  _isNegative: CUnsignedInt(isNegative ? 1 : 0),
                  _isCompact: CUnsignedInt(isCompact ? 1 : 0),
                  _reserved: 0,
                  _mantissa: mantissa)
    }
    
    public func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(_exponent, forKey: .exponent)
        try container.encode(_length, forKey: .length)
        try container.encode(_isNegative == 0 ? false : true, forKey: .isNegative)
        try container.encode(_isCompact == 0 ? false : true, forKey: .isCompact)
        
        var mantissaContainer = container.nestedUnkeyedContainer(forKey: .mantissa)
        try mantissaContainer.encode(_mantissa.0)
        try mantissaContainer.encode(_mantissa.1)
        try mantissaContainer.encode(_mantissa.2)
        try mantissaContainer.encode(_mantissa.3)
        try mantissaContainer.encode(_mantissa.4)
        try mantissaContainer.encode(_mantissa.5)
        try mantissaContainer.encode(_mantissa.6)
        try mantissaContainer.encode(_mantissa.7)
    }
}
