NSDecimalNumber(x).intValue returns -2, 0, 15 and 199, depending on the amount of decimals in x (x = 199.999...5)
It's clearly a foundation bug, probably the one mentioned by Martin R in the comments.
I experimented in Playground (Swift 5) and found that the comment on that bug that int32Value
works correctly is true.
import Foundation
let pQuantity = Decimal(string: "0.2857142857142857")!
let pPrice = Decimal(string: "7.00000000000000035")!
let calced = NSDecimalNumber(decimal: pQuantity * pPrice * Decimal(integerLiteral: 100)) // 200
let decimal = calced.decimalValue // 199.9999999999999999999999999999995
let integer = calced.int32Value // 200
NSDecimalNumber(decimal: Decimal(string: "199.9999999999999999999999999999995")!).uint32Value // 200
NSDecimalNumber(decimal: Decimal(string: "199.9999999999999995")!).int32Value // 200
NSDecimalNumber(decimal: Decimal(string: "199.99999999999999995")!).int32Value // 200
NSDecimalNumber(decimal: Decimal(string: "199.999999999999999995")!).int32Value // 200
Also, as you can see uint32Value
also works correctly. However, none of the 64 bit variants work.
Provided you are sure that your result will fit into an Int32
you can use that as a work around until they fix it, which is probably never, given that the bug has been outstanding for a while.
How to store 1.66 in NSDecimalNumber
In
let number:NSDecimalNumber = 1.66
the right-hand side is a floating point number which cannot represent
the value "1.66" exactly. One option is to create the decimal number
from a string:
let number = NSDecimalNumber(string: "1.66")
print(number) // 1.66
Another option is to use arithmetic:
let number = NSDecimalNumber(value: 166).dividing(by: 100)
print(number) // 1.66
With Swift 3 you may consider to use the "overlay value type" Decimal
instead, e.g.
let num = Decimal(166)/Decimal(100)
print(num) // 1.66
Yet another option:
let num = Decimal(sign: .plus, exponent: -2, significand: 166)
print(num) // 1.66
Addendum:
Related discussions in the Swift forum:
- Exact NSDecimalNumber via literal
- ExpressibleByFractionLiteral
Related bug reports:
- SR-3317
Literal protocol for decimal literals should support precise decimal accuracy, closed as a duplicate of - SR-920
Re-design builtin compiler protocols for literal convertible types.
Examples of doing decimal math in iPhone
To init:
NSString *number = @"123.4";
NSDecimalNumber *myDecimal = [[NSDecimalNumber alloc] initWithString: number];
To do what you want to do:
NSDecimalNumber *sum = [[NSDecimalNumber alloc] initWithDecimal:[balance decimalNumberByMultiplyingBy: interest_rate];
How?
Well you make a NSDecimalNumber and alloc and then initWithDecimal. What decimal? balance multiplied (decimalNumberByMultiplyingBy) by interest_rate.
Swift 3 : Decimal to Int
This is my updated answer (thanks to Martin R and the OP for the remarks). The OP's problem was just casting the pow(x: Decimal,y: Int) -> Decimal
function to an Int after subtracting 1 from the result. I have answered the question with the help of this SO post for NSDecimal and Apple's documentation on Decimal. You have to convert your result to an NSDecimalNumber, which can in turn be casted into an Int:
let size = Decimal(2)
let test = pow(size, 2) - 1
let result = NSDecimalNumber(decimal: test)
print(Int(result)) // testing the cast to Int
calculated double return scientific notation
The number itself is correct as scientific notation. If you want to present a formatted number to the user, it should be a String. Here's working code using a NumberFormatter:
extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> String? {
let fmt = NumberFormatter()
fmt.numberStyle = .decimal
fmt.maximumFractionDigits = places
return fmt.string(from: self as NSNumber)
}
}
let price = tickerObj.price ?? 0
let quantity = Double(self.activeTextField.text ?? "0") ?? 0
let value = quantity / price
topValueField.text = "\(value.rounded(toPlaces: 8) ?? "Unknown")"
Related Topics
Swift Property Observer in Protocol Extension
Failed to Get Descriptors for Extensionbundleid
Add Custom Header to Collection View Swift
Weak VS Unowned in Swift. What Are the Internal Differences
What Is the "@Exported" Attribute in Swift
Po Swift String "Unresolved Identifier"
Delete All Characters After a Certain Character from a String in Swift
How to Repeat Animation (Using Uiviewpropertyanimator) Certain Number of Times
Swift - How to Create a View with a Shape Cropped in It
Swift 4 - Notification Center Addobserver Issue
iOS Tabbar Item Title Issue in iOS13
How to Animate Transition Between Views in Swiftui
Get Index in Foreach in Swiftui
Swift - Class Method Which Must Be Overridden by Subclass
Difference Between Scenedelegate and Appdelegate
How to Disambiguate a Type and a Module With the Same Name