Decimal values get remove when convert from String to Decimal in Swift - ios

Please check this example
let strValue = "12.00"
let decimalValue = Decimal(string: strValue) // 12
it always returns 12 not 12.00
I also try with NSNumber, Float, and Double but it always remove zeros.
Can you please help me with this thanks in advance

Like martin said. 12 and 12.00 is the same number. It doesn't mathematical matter how many 0 are behind the comma.
While a number stays the same, the representation is a different topic.
String(format: "%.6f", 12) will give 12.000000 as String.
Edit:
A Decimal is a Struct. The meaning of the numbers stays the same. Throw this in a playground.
import UIKit
let decimal = Decimal(12.0000000000)
let justAnInt = 12
let sameDecimal = decimal == Decimal(justAnInt)
See? There is no such thing as infinite 0 in math. Zero is finite. A Decimal from 12.000000 and a Decimal created from 12 are the same.

There is no difference between 12 & 12.00.
The only thing we need is to present the value to user., for that you could use formatted string.
Like:
String(format: "%.2f", floatValue)

Related

"%.2f" is rounding my number up instead of cutting

I have the following number
7.9775609756097534
and I'm using the code below to only show two decimals
let formatted = String(format: "Angle: %.2f", angle)
the problem is that the result is:
7.98
instead of
7.97
For cases such as yours we use NumberFormatter. It is a class designed to do what you need and more. For your case it should be enough to use the following:
let numberFormatter = NumberFormatter()
numberFormatter.roundingMode = .down
numberFormatter.minimumFractionDigits = 2
numberFormatter.maximumFractionDigits = 2
numberFormatter.string(from: 1.236)
This now locks fraction digits to be exactly 2. By increasing minimum fraction digits more "0" may be appended as in 0.10 may become 0.100. Maximum fraction digits will simply restrict up to what point the number will be displayed.
There are other options as well such as making 1234567.89 show as 1.234.567,89 which is really nice for users that are used to such formatting.
Alternatively, you can do bit string manipulation
let numberInFloat:Float = 7.9775609756097534
let numberInString: String = String(format: "%f", numberInFloat)
let numberParts = numberInString.components(separatedBy: ".")
print(String(format: "Output: %#.%#", String(numberParts[0]), String(numberParts[1].prefix(2))))
Output: 7.97

Find digit at index of NSDecimalNumber

Is it possible to find the number at an index of an NSDecimalNumber?
For example is something like this possible?
var a: NSDecimalNumber = 10.00123456789
var indexOfa = a(index: 6)
//indexOfa = 6 (6th position from the left)
I'm basically trying to make a custom rounding function that rounds down on x.xx5 and rounds up on x.xx6.
For example:
67.5558 is rounded to 67.55.
67.5568 is rounded to 67.56.
...Not a duplicate of rounding question. I'm asking specifically here how to find a digit at a specified index of an NSDecimalNumber.
Also the answer you linked doesn't answer my question. I can use the rounding behaviours for NSDecimalNumber but it rounds up on .5 I need it to round down on .5 and up on .6. I can create my own custom rounding function if I could find the index of the 2nd decimal number.
I have a solution that works. But its horrible. There's a few NSDecimalNumber extensions in there but you can probably guess what they are doing. And I'm sure theres a better way...
public func currencyRoundDown() -> NSDecimalNumber {
let rounded: NSDecimalNumber
let toThree = self.roundDown(3)
let lower = self.roundDown(2).adding(0.005)
if lower.moreThan(toThree) || lower.same(toThree) {
rounded = toThree.roundDown(2)
} else {
rounded = toThree.roundUp(2)
}
return rounded
}
Is it possible to find the number at an index of an NSDecimalNumber?
Let's consider how to do it with a Double. In this rendering, the "index" counts from the decimal point.
Multiply by 10 to the index, to bring the index digit into the 1s place. Now take the remainder modulo 10. That is the digit in question.
let d = 1234.56789 // the 5 is 1, the 6 is 2, the 7 is 3 ...
let place = 3
let shift = pow(10.0, Double(place)) * d
let digit = Int(shift) % 10 // 7

decimal place value not working in swift

I'm not really sure what I am doing wrong here. I have a double:
let distanceInMiles = distanceInMeters/1609.344 and the results are 2.99685063032388e-09
But I want to round the number to one decimal place, so I do this:
let miles = String(format: "%.1f", distanceInMiles)
But when I print it out miles = 0.0. The decimal place works but it turns my number into 0 instead of 2.9
2.99685063032388e-09 is not equal to 2.9, it is 0.00000000299685063032388
http://www.wolframalpha.com/input/?i=2.99685063032388e-09
There is actually a cool way to do this, using the exponent format specifier instead of float. (From this list https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html)
let miles = String(format: "%.1e", distanceInMiles)

String to Double conversion loses precision in Swift

I want to covert a string to double and keep the same value:
let myStr = "2.40"
let numberFormatter = NSNumberFormatter()
numberFormatter.locale = NSLocale(localeIdentifier: "fr_FR")
let myDouble = numberFormatter.numberFromString(myStr)?.doubleValue ?? 0.0
myDouble is now
Double? 2.3999999999999999
So how to convert "2.40" to exact be 2.40 as Double ??
Update:
Even rounding after conversion does not seem to work
I don't want to print, I want to calculate and it's important that the number should be correct, it's Money calculation and rates
First off: you don't! What you encountered here is called floating point inaccuracy. Computers cannot store every number precisely. 2.4 cannot be stored lossless within a floating point type.
Secondly: Since floating point is always an issue and you are dealing with money here (I guess you are trying to store 2.4 franc) your number one solution is: don't use floating point numbers. Use the NSNumber you get from the numberFromString and do not try to get a Double out of it.
Alternatively shift the comma by multiplying and store it as Int.
The first solutions might look something like:
if let num = myDouble {
let value = NSDecimalNumber(decimal: num.decimalValue)
let output = value.decimalNumberByMultiplyingBy(NSDecimalNumber(integer: 10))
}

Round function doesn't work as expected

I'm trying round a Double value with two decimal places:
var x = 0.68999999999999995
var roundX = round(x * 100.0) / 100.0
println(roundX) // print 0.69
If print the value is correct.. but the var value isn't that i expect, continue 0.68999999999999995
I need the Double value... not String like other StackOverflow answers :(
Floating point numbers like doubles do not have a number of decimal places. They store values in binary, and a value like .69 can't be represented exactly. It's just the nature of binary floating point on computers.
Use a number formatter, or use String(format:) as #KRUKUSA suggests
var x:Double = 0.68999999999999995
let stringWithTwoDecimals = String(format: "%.2f", x)
println(stringWithTwoDecimals)

Resources