Java BigDecimal in Swift
Asked Answered
S

2

12

What data type I can use for parsing Java BigDecimal? In Objective - C it can be done by using NSDecimalNumber. Do I have Swift-native solution (without using NSDecimalNumber)?

Sodomy answered 23/8, 2016 at 20:44 Comment(4)
Just use NSDecimalNumber. It works fine from Swift.Fuzz
You don't understand. I want native for Swift solution (of course, if exist).Sodomy
I do understand. A "native" solution doesn't exist. But NSDecimalNumber works fine. And if you want, you can define operators that make it behave more like a native solution so operators like +, -, etc., work as you'd expect.Fuzz
@PRECover Perhaps you should have mentioned that in your question.Conglutinate
D
12

This may not be what you want, as you are saying swift-native solution. But in Swift 3, an old C-struct based NSDecimal is imported as Decimal, and a big re-arrangement for it has been done as to say "it is nearly Swift-native".

let deca = 1.23 as Decimal //<- This actually may produce some conversion error, while `ExpressibleByFloatLiteral` uses `Double` as an intermediate value.
let decb = 0.01 as Decimal
print(deca + decb == 1.24) //->true

UPDATE Added a simple example, where you can find a calculation error in Double (binary floating point system). (Tested in Xcode 8 beta 6.)

let dblc = 0.000001
let dbld = 100 as Double
let dble = 0.0001
print(dblc * dbld == dble) //->false (as Double cannot represent decimal fractions precisely)

let decc = Decimal(string: "0.000001")! //<- avoiding conversion error
let decd = 100 as Decimal //<- integer literal may not generate conversion error
let dece = Decimal(string: "0.0001")!
print(decc * decd == dece) //->true
Disinfect answered 23/8, 2016 at 21:29 Comment(2)
Swift Decimal only goes up to 128-bit precision though.Chlorinate
@CommaToast, True, if that can be an issue, you may need to find another solution. This answer is written under the assumption In Objective - C it can be done by using NSDecimalNumber.Disinfect
C
1

You can also use j2obj, a Google project that translates Java code to Objective C, including all the Java types like BigInteger and BigDecimal. Using this I was able to make an XCFramework that incorporates support for those native Java types, including all their functionality from Java, into Swift. Pretty cool, although it's not a small framework.

Basically you just clone j2objc and build locally (cd to its directory and "make dist -j8"). Then make a new Xcode project with a framework target. Follow the steps on Google's j2objc site to add your J2OBJC_HOME to build settings and add the library and header search paths to your new framework project.

Now in your framework's public header you'll want to import "java/math/BigDecimal.h", and you'll want to add to your framework's headers a copy of all the headers needed by BigDecimal.m and its dependencies.

Lastly archive your framework for hardware platforms and build for simulator, then make an XCFramework including all those built .frameworks from the archives and your DerivedData.

Once you have the XCFramework you can add it to any other project whose architectures it supports. And from there use it in code. Note you have to initialize j2bjc classes before making an instance of them.

Chlorinate answered 9/2, 2021 at 20:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.