Still Missing: Fixed Decimal Numerical Type.


(Ted van Gaalen) #1

There is still no fixed decimal numerical type available in Swift!

It should be implemented *as soon as possible*
because the fixed decimal type is really needed
for applications working with financial and statistical data!

E.g.
var depositPromille: Decimal(10,3) = -1234.56
typealias Money = Decimal(20,2)

Important: Implementation should be on a low level
and must be very, very efficient!
This is because usually in financial applications
very large amounts of data (e.g. bank accounts) are processed.

I’d suggest that Swift could deploy already existing
Fixed Decimal library functions available.
In fact, many do exist, for example here:
http://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01152.html

Of course, the fixed decimal type is also available in most relational databases,
currently there is no 1:1 way to get this type of data DB <—> Swift,
and to process it easily in Swift. One now has to convert it e.g.
to large integers, thereby also somehow remembering the decimal fraction.
Yes, one could write a class/struct for it, but one also has
to implement all the arithmetic involved, with also needs
rounding, truncation, etc. It would also be too slow.

For those still considering using floating point types
for this purpose e.g. Double: Forget it, because
floating point types don’t have the required exact precision.
E.g. € 234,565,098.01 // the one cent at the end is important!

For some idea on how this could be implemented in the Swift language
please read a PL/1 manual, like this one:

http://www.ibm.com/support/knowledgecenter/#!/SSY2V3_4.3.0/com.ibm.entpli.doc_4.3/lr/preface_plugin.htm

especially under sub-topic “Data elements”

Kind Regards
TedvG


(Brent Royal-Gordon) #2

var depositPromille: Decimal(10,3) = -1234.56
typealias Money = Decimal(20,2)

There is no mechanism to parameterize types like this. (Specifically, you can only parameterize a generic type with types, not integers or other values.) That makes this a fairly large effort—certainly not impossible, but more than just writing some code and putting it in the standard library. "As soon as possible" will still be quite a ways away, and may not even come in this Swift version.

As a stopgap, use NSDecimal (which is not fixed, but does provide decimal arithmetic) or write your own Money struct:

  struct Money {
    private var cents: Int
    
    init(_ value: Int) {
      cents = value * 100
    }
    
    init(cents: Int) {
      self.cents = cents
    }
    
    init(approximating value: Double) {
      cents = Int(value * 100)
    }
  }
  
  extension Int {
    init(approximating value: Money) {
      self = value.cents / 100
    }
    init(cents value: Money) {
      self = value.cents
    }
  }
  
  extension Double {
    init(approximating value: Money) {
      self = Double(value.cents) / 100
    }
  }
  
  extension Money: StringLiteralConvertible {
    // or FloatLiteralConvertible if you think you can get away with it
    ...
  }
  
  extension Money: Hashable, Comparable, CustomStringConvertible {
    ...
  }
  
  func + (lhs: Money, rhs: Money) -> Money { return Money(cents: lhs.cents + rhs.cents) }
  func * (lhs: Money, rhs: Int) -> Money { return Money(cents: lhs.cents * rhs) }
  // etc.

···

--
Brent Royal-Gordon
Architechies


(Michael Gottesman) #3

+CC Steve

···

On Mar 30, 2016, at 6:09 AM, Ted F.A. van Gaalen via swift-evolution <swift-evolution@swift.org> wrote:

There is still no fixed decimal numerical type available in Swift!

It should be implemented *as soon as possible*
because the fixed decimal type is really needed
for applications working with financial and statistical data!

E.g.
var depositPromille: Decimal(10,3) = -1234.56
typealias Money = Decimal(20,2)

Important: Implementation should be on a low level
and must be very, very efficient!
This is because usually in financial applications
very large amounts of data (e.g. bank accounts) are processed.

I’d suggest that Swift could deploy already existing
Fixed Decimal library functions available.
In fact, many do exist, for example here:
http://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01152.html <http://gcc.gnu.org/onlinedocs/gcc-4.6.0/libstdc++/api/a01152.html>

Of course, the fixed decimal type is also available in most relational databases,
currently there is no 1:1 way to get this type of data DB <—> Swift,
and to process it easily in Swift. One now has to convert it e.g.
to large integers, thereby also somehow remembering the decimal fraction.
Yes, one could write a class/struct for it, but one also has
to implement all the arithmetic involved, with also needs
rounding, truncation, etc. It would also be too slow.

For those still considering using floating point types
for this purpose e.g. Double: Forget it, because
floating point types don’t have the required exact precision.
E.g. € 234,565,098.01 // the one cent at the end is important!

For some idea on how this could be implemented in the Swift language
please read a PL/1 manual, like this one:

http://www.ibm.com/support/knowledgecenter/#!/SSY2V3_4.3.0/com.ibm.entpli.doc_4.3/lr/preface_plugin.htm

especially under sub-topic “Data elements”

Kind Regards
TedvG
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution