How to round Int with two digits using NSNumberFormatter? - ios

I simply created extensions:
extension NumberFormatter {
convenience init(digits: Int) {
self.init()
self.maximumFractionDigits = digits
self.minimumFractionDigits = digits
}
}
extension Int {
var descriptivePrice: String {
return NumberFormatter(digits: 2).string(from: NSNumber(value: Double(self * 100/10000))) ?? ""
}
}
And testing this:
func testDescriptivePrice() {
XCTAssertEqual(2345.descriptivePrice, "23,45") //23,00
XCTAssertEqual(20000.descriptivePrice, "200,00")
XCTAssertEqual(20.descriptivePrice, "0,20") //0,00
XCTAssertEqual(2.descriptivePrice, "0,02") //0,00
}
Why my tests fail?

This has nothing to do with number formatters, and everything about how you convert your ints to doubles:
Double(self * 100/10000)
Here you are converting to Double after you divide, so you are doing integer division. In other words, you are just removing the last two digits of an integer. In 2345.descriptivePrice for example, the 45 part is already lost when you do 234500 / 10000 (= 23), before any NumberFormatter-related stuff happens.
You should convert self to Double first, then divide:
Double(self) / 100

Related

BMI Calculation Xcode [duplicate]

Can anyone tell me how to round a double value to x number of decimal places in Swift?
I have:
var totalWorkTimeInHours = (totalWorkTime/60/60)
With totalWorkTime being an NSTimeInterval (double) in second.
totalWorkTimeInHours will give me the hours, but it gives me the amount of time in such a long precise number e.g. 1.543240952039......
How do I round this down to, say, 1.543 when I print totalWorkTimeInHours?
You can use Swift's round function to accomplish this.
To round a Double with 3 digits precision, first multiply it by 1000, round it and divide the rounded result by 1000:
let x = 1.23556789
let y = Double(round(1000 * x) / 1000)
print(y) /// 1.236
Unlike any kind of printf(...) or String(format: ...) solutions, the result of this operation is still of type Double.
EDIT:
Regarding the comments that it sometimes does not work, please read this: What Every Programmer Should Know About Floating-Point Arithmetic
Extension for Swift 2
A more general solution is the following extension, which works with Swift 2 & iOS 9:
extension Double {
/// Rounds the double to decimal places value
func roundToPlaces(places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return round(self * divisor) / divisor
}
}
Extension for Swift 3
In Swift 3 round is replaced by rounded:
extension Double {
/// Rounds the double to decimal places value
func rounded(toPlaces places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
Example which returns Double rounded to 4 decimal places:
let x = Double(0.123456789).roundToPlaces(4) // x becomes 0.1235 under Swift 2
let x = Double(0.123456789).rounded(toPlaces: 4) // Swift 3 version
How do I round this down to, say, 1.543 when I print totalWorkTimeInHours?
To round totalWorkTimeInHours to 3 digits for printing, use the String constructor which takes a format string:
print(String(format: "%.3f", totalWorkTimeInHours))
With Swift 5, according to your needs, you can choose one of the 9 following styles in order to have a rounded result from a Double.
#1. Using FloatingPoint rounded() method
In the simplest case, you may use the Double rounded() method.
let roundedValue1 = (0.6844 * 1000).rounded() / 1000
let roundedValue2 = (0.6849 * 1000).rounded() / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#2. Using FloatingPoint rounded(_:) method
let roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000
let roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#3. Using Darwin round function
Foundation offers a round function via Darwin.
import Foundation
let roundedValue1 = round(0.6844 * 1000) / 1000
let roundedValue2 = round(0.6849 * 1000) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#4. Using a Double extension custom method built with Darwin round and pow functions
If you want to repeat the previous operation many times, refactoring your code can be a good idea.
import Foundation
extension Double {
func roundToDecimal(_ fractionDigits: Int) -> Double {
let multiplier = pow(10, Double(fractionDigits))
return Darwin.round(self * multiplier) / multiplier
}
}
let roundedValue1 = 0.6844.roundToDecimal(3)
let roundedValue2 = 0.6849.roundToDecimal(3)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#5. Using NSDecimalNumber rounding(accordingToBehavior:) method
If needed, NSDecimalNumber offers a verbose but powerful solution for rounding decimal numbers.
import Foundation
let scale: Int16 = 3
let behavior = NSDecimalNumberHandler(roundingMode: .plain, scale: scale, raiseOnExactness: false, raiseOnOverflow: false, raiseOnUnderflow: false, raiseOnDivideByZero: true)
let roundedValue1 = NSDecimalNumber(value: 0.6844).rounding(accordingToBehavior: behavior)
let roundedValue2 = NSDecimalNumber(value: 0.6849).rounding(accordingToBehavior: behavior)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#6. Using NSDecimalRound(_:_:_:_:) function
import Foundation
let scale = 3
var value1 = Decimal(0.6844)
var value2 = Decimal(0.6849)
var roundedValue1 = Decimal()
var roundedValue2 = Decimal()
NSDecimalRound(&roundedValue1, &value1, scale, NSDecimalNumber.RoundingMode.plain)
NSDecimalRound(&roundedValue2, &value2, scale, NSDecimalNumber.RoundingMode.plain)
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
#7. Using NSString init(format:arguments:) initializer
If you want to return a NSString from your rounding operation, using NSString initializer is a simple but efficient solution.
import Foundation
let roundedValue1 = NSString(format: "%.3f", 0.6844)
let roundedValue2 = NSString(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685
#8. Using String init(format:_:) initializer
Swift’s String type is bridged with Foundation’s NSString class. Therefore, you can use the following code in order to return a String from your rounding operation:
import Foundation
let roundedValue1 = String(format: "%.3f", 0.6844)
let roundedValue2 = String(format: "%.3f", 0.6849)
print(roundedValue1) // prints 0.684
print(roundedValue2) // prints 0.685
#9. Using NumberFormatter
If you expect to get a String? from your rounding operation, NumberFormatter offers a highly customizable solution.
import Foundation
let formatter = NumberFormatter()
formatter.numberStyle = NumberFormatter.Style.decimal
formatter.roundingMode = NumberFormatter.RoundingMode.halfUp
formatter.maximumFractionDigits = 3
let roundedValue1 = formatter.string(from: 0.6844)
let roundedValue2 = formatter.string(from: 0.6849)
print(String(describing: roundedValue1)) // prints Optional("0.684")
print(String(describing: roundedValue2)) // prints Optional("0.685")
In Swift 5.5 and Xcode 13.2:
let pi: Double = 3.14159265358979
String(format:"%.2f", pi)
Example:
PS.: It still the same since Swift 2.0 and Xcode 7.2
This is a fully worked code
Swift 3.0/4.0/5.0 , Xcode 9.0 GM/9.2 and above
let doubleValue : Double = 123.32565254455
self.lblValue.text = String(format:"%.f", doubleValue)
print(self.lblValue.text)
output - 123
let doubleValue : Double = 123.32565254455
self.lblValue_1.text = String(format:"%.1f", doubleValue)
print(self.lblValue_1.text)
output - 123.3
let doubleValue : Double = 123.32565254455
self.lblValue_2.text = String(format:"%.2f", doubleValue)
print(self.lblValue_2.text)
output - 123.33
let doubleValue : Double = 123.32565254455
self.lblValue_3.text = String(format:"%.3f", doubleValue)
print(self.lblValue_3.text)
output - 123.326
Building on Yogi's answer, here's a Swift function that does the job:
func roundToPlaces(value:Double, places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return round(value * divisor) / divisor
}
In Swift 3.0 and Xcode 8.0:
extension Double {
func roundTo(places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
Use this extension like so:
let doubleValue = 3.567
let roundedValue = doubleValue.roundTo(places: 2)
print(roundedValue) // prints 3.56
Swift 4, Xcode 10
yourLabel.text = String(format:"%.2f", yourDecimalValue)
The code for specific digits after decimals is:
var a = 1.543240952039
var roundedString = String(format: "%.3f", a)
Here the %.3f tells the swift to make this number rounded to 3 decimal places.and if you want double number, you may use this code:
// String to Double
var roundedString = Double(String(format: "%.3f", b))
Use the built in Foundation Darwin library
SWIFT 3
extension Double {
func round(to places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return Darwin.round(self * divisor) / divisor
}
}
Usage:
let number:Double = 12.987654321
print(number.round(to: 3))
Outputs: 12.988
If you want to round Double values, you might want to use Swift Decimal so you don't introduce any errors that can crop up when trying to math with these rounded values. If you use Decimal, it can accurately represent decimal values of that rounded floating point value.
So you can do:
extension Double {
/// Convert `Double` to `Decimal`, rounding it to `scale` decimal places.
///
/// - Parameters:
/// - scale: How many decimal places to round to. Defaults to `0`.
/// - mode: The preferred rounding mode. Defaults to `.plain`.
/// - Returns: The rounded `Decimal` value.
func roundedDecimal(to scale: Int = 0, mode: NSDecimalNumber.RoundingMode = .plain) -> Decimal {
var decimalValue = Decimal(self)
var result = Decimal()
NSDecimalRound(&result, &decimalValue, scale, mode)
return result
}
}
Then, you can get the rounded Decimal value like so:
let foo = 427.3000000002
let value = foo.roundedDecimal(to: 2) // results in 427.30
And if you want to display it with a specified number of decimal places (as well as localize the string for the user's current locale), you can use a NumberFormatter:
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
if let string = formatter.string(for: value) {
print(string)
}
A handy way can be the use of extension of type Double
extension Double {
var roundTo2f: Double {return Double(round(100 *self)/100) }
var roundTo3f: Double {return Double(round(1000*self)/1000) }
}
Usage:
let regularPie: Double = 3.14159
var smallerPie: Double = regularPie.roundTo3f // results 3.142
var smallestPie: Double = regularPie.roundTo2f // results 3.14
This is a sort of a long workaround, which may come in handy if your needs are a little more complex. You can use a number formatter in Swift.
let numberFormatter: NSNumberFormatter = {
let nf = NSNumberFormatter()
nf.numberStyle = .DecimalStyle
nf.minimumFractionDigits = 0
nf.maximumFractionDigits = 1
return nf
}()
Suppose your variable you want to print is
var printVar = 3.567
This will make sure it is returned in the desired format:
numberFormatter.StringFromNumber(printVar)
The result here will thus be "3.6" (rounded). While this is not the most economic solution, I give it because the OP mentioned printing (in which case a String is not undesirable), and because this class allows for multiple parameters to be set.
Either:
Using String(format:):
Typecast Double to String with %.3f format specifier and then back to Double
Double(String(format: "%.3f", 10.123546789))!
Or extend Double to handle N-Decimal places:
extension Double {
func rounded(toDecimalPlaces n: Int) -> Double {
return Double(String(format: "%.\(n)f", self))!
}
}
By calculation
multiply with 10^3, round it and then divide by 10^3...
(1000 * 10.123546789).rounded()/1000
Or extend Double to handle N-Decimal places:
extension Double {
func rounded(toDecimalPlaces n: Int) -> Double {
let multiplier = pow(10, Double(n))
return (multiplier * self).rounded()/multiplier
}
}
I would use
print(String(format: "%.3f", totalWorkTimeInHours))
and change .3f to any number of decimal numbers you need
This is more flexible algorithm of rounding to N significant digits
Swift 3 solution
extension Double {
// Rounds the double to 'places' significant digits
func roundTo(places:Int) -> Double {
guard self != 0.0 else {
return 0
}
let divisor = pow(10.0, Double(places) - ceil(log10(fabs(self))))
return (self * divisor).rounded() / divisor
}
}
// Double(0.123456789).roundTo(places: 2) = 0.12
// Double(1.23456789).roundTo(places: 2) = 1.2
// Double(1234.56789).roundTo(places: 2) = 1200
The best way to format a double property is to use the Apple predefined methods.
mutating func round(_ rule: FloatingPointRoundingRule)
FloatingPointRoundingRule is a enum which has following possibilities
Enumeration Cases:
case awayFromZero
Round to the closest allowed value whose magnitude is greater than or equal to that of the source.
case down
Round to the closest allowed value that is less than or equal to the source.
case toNearestOrAwayFromZero
Round to the closest allowed value; if two values are equally close, the one with greater magnitude is chosen.
case toNearestOrEven
Round to the closest allowed value; if two values are equally close, the even one is chosen.
case towardZero
Round to the closest allowed value whose magnitude is less than or equal to that of the source.
case up
Round to the closest allowed value that is greater than or equal to the source.
var aNumber : Double = 5.2
aNumber.rounded(.up) // 6.0
round a double value to x number of decimal
NO. of digits after decimal
var x = 1.5657676754
var y = (x*10000).rounded()/10000
print(y) // 1.5658
var x = 1.5657676754
var y = (x*100).rounded()/100
print(y) // 1.57
var x = 1.5657676754
var y = (x*10).rounded()/10
print(y) // 1.6
For ease to use, I created an extension:
extension Double {
var threeDigits: Double {
return (self * 1000).rounded(.toNearestOrEven) / 1000
}
var twoDigits: Double {
return (self * 100).rounded(.toNearestOrEven) / 100
}
var oneDigit: Double {
return (self * 10).rounded(.toNearestOrEven) / 10
}
}
var myDouble = 0.12345
print(myDouble.threeDigits)
print(myDouble.twoDigits)
print(myDouble.oneDigit)
The print results are:
0.123
0.12
0.1
Thanks for the inspiration of other answers!
Not Swift but I'm sure you get the idea.
pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;
Swift 5
using String method
var yourDouble = 3.12345
//to round this to 2 decimal spaces i could turn it into string
let roundingString = String(format: "%.2f", myDouble)
let roundedDouble = Double(roundingString) //and than back to double
// result is 3.12
but it's more accepted to use extension
extension Double {
func round(to decimalPlaces: Int) -> Double {
let precisionNumber = pow(10,Double(decimalPlaces))
var n = self // self is a current value of the Double that you will round
n = n * precisionNumber
n.round()
n = n / precisionNumber
return n
}
}
and then you can use:
yourDouble.round(to:2)
This seems to work in Swift 5.
Quite surprised there isn't a standard function for this already.
//Truncation of Double to n-decimal places with rounding
extension Double {
func truncate(to places: Int) -> Double {
return Double(Int((pow(10, Double(places)) * self).rounded())) / pow(10, Double(places))
}
}
To avoid Float imperfections use Decimal
extension Float {
func rounded(rule: NSDecimalNumber.RoundingMode, scale: Int) -> Float {
var result: Decimal = 0
var decimalSelf = NSNumber(value: self).decimalValue
NSDecimalRound(&result, &decimalSelf, scale, rule)
return (result as NSNumber).floatValue
}
}
ex.
1075.58 rounds to 1075.57 when using Float with scale: 2 and .down
1075.58 rounds to 1075.58 when using Decimal with scale: 2 and .down
var n = 123.111222333
n = Double(Int(n * 10.0)) / 10.0
Result: n = 123.1
Change 10.0 (1 decimal place) to any of 100.0 (2 decimal place), 1000.0 (3 decimal place) and so on, for the number of digits you want after decimal..
The solution worked for me. XCode 13.3.1 & Swift 5
extension Double {
func rounded(decimalPoint: Int) -> Double {
let power = pow(10, Double(decimalPoint))
return (self * power).rounded() / power
}
}
Test:
print(-87.7183123123.rounded(decimalPoint: 3))
print(-87.7188123123.rounded(decimalPoint: 3))
print(-87.7128123123.rounded(decimalPoint: 3))
Result:
-87.718
-87.719
-87.713
I found this wondering if it is possible to correct a user's input. That is if they enter three decimals instead of two for a dollar amount. Say 1.111 instead of 1.11 can you fix it by rounding? The answer for many reasons is no! With money anything over i.e. 0.001 would eventually cause problems in a real checkbook.
Here is a function to check the users input for too many values after the period. But which will allow 1., 1.1 and 1.11.
It is assumed that the value has already been checked for successful conversion from a String to a Double.
//func need to be where transactionAmount.text is in scope
func checkDoublesForOnlyTwoDecimalsOrLess()->Bool{
var theTransactionCharacterMinusThree: Character = "A"
var theTransactionCharacterMinusTwo: Character = "A"
var theTransactionCharacterMinusOne: Character = "A"
var result = false
var periodCharacter:Character = "."
var myCopyString = transactionAmount.text!
if myCopyString.containsString(".") {
if( myCopyString.characters.count >= 3){
theTransactionCharacterMinusThree = myCopyString[myCopyString.endIndex.advancedBy(-3)]
}
if( myCopyString.characters.count >= 2){
theTransactionCharacterMinusTwo = myCopyString[myCopyString.endIndex.advancedBy(-2)]
}
if( myCopyString.characters.count > 1){
theTransactionCharacterMinusOne = myCopyString[myCopyString.endIndex.advancedBy(-1)]
}
if theTransactionCharacterMinusThree == periodCharacter {
result = true
}
if theTransactionCharacterMinusTwo == periodCharacter {
result = true
}
if theTransactionCharacterMinusOne == periodCharacter {
result = true
}
}else {
//if there is no period and it is a valid double it is good
result = true
}
return result
}
You can add this extension :
extension Double {
var clean: String {
return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)
}
}
and call it like this :
let ex: Double = 10.123546789
print(ex.clean) // 10.12
Here's one for SwiftUI if you need a Text element with the number value.
struct RoundedDigitText : View {
let digits : Int
let number : Double
var body : some View {
Text(String(format: "%.\(digits)f", number))
}
}
//find the distance between two points
let coordinateSource = CLLocation(latitude: 30.7717625, longitude:76.5741449 )
let coordinateDestination = CLLocation(latitude: 29.9810859, longitude: 76.5663599)
let distanceInMeters = coordinateSource.distance(from: coordinateDestination)
let valueInKms = distanceInMeters/1000
let preciseValueUptoThreeDigit = Double(round(1000*valueInKms)/1000)
self.lblTotalDistance.text = "Distance is : \(preciseValueUptoThreeDigit) kms"

Swift 3 : Decimal to Int

I tried to convert Decimal to Int with the follow code:
Int(pow(Decimal(size), 2) - 1)
But I get:
.swift:254:43: Cannot invoke initializer for type 'Int' with an argument list of type '(Decimal)'
Here I know pow is returning a Decimal but it seems that Int has no constructors and member functions to convert Decimal to Int.
How can I convert Decimal to Int in Swift 3?
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
let decimalToInt = (yourDecimal as NSDecimalNumber).intValue
or as #MartinR suggested:
let decimalToInt = NSDecimalNumber(decimal: yourDecimal).intValue
If you have a very long decimal, then beware of rounding errors
let decimal = Decimal(floatLiteral: 100.123456)
let intValue = (decimal as NSDecimalNumber).intValue // This is 100
However
let veryLargeDecimal = Decimal(floatLiteral: 100.123456789123)
let intValue = (veryLargeDecimal as NSDecimalNumber).intValue // This is -84 !
I ensured I rounded my Decimal before I converted it to an Int, using NSDecimalRound (which you can put in an extension of Decimal).
var veryLargeDecimal = Decimal(floatLiteral: 100.123456789123)
var rounded = Decimal()
NSDecimalRound(&rounded, &veryLargeDecimal, 0, .down)
let intValue = (rounded as NSDecimalNumber).intValue // This is now 100
There is nothing wrong with either of the posted answers, but I would like to offer up an extension that reduces the verbosity for scenarios where you need to use this frequently.
extension Decimal {
var int: Int {
return NSDecimalNumber(decimal: self).intValue
}
}
To call it:
let powerDecimal = pow(2, 2) // Output is Decimal
let powerInt = powerDecimal.int // Output is now an Int
Unfortunately there is an intermittent failure using some of the methods provided.
NSDecimalNumber(decimal: <num>).intValue can produce unexpected results...
(lldb) po NSDecimalNumber(decimal: self)
10.6666666666666666666666666666666666666
(lldb) po NSDecimalNumber(decimal: self).intValue
0
I think there is more of a discussion on it here, and #Martin was pointing it out here
Instead of using the decimal value directly, I made a work around that converts the decimal to a whole number before converting the Decimal to an Int.
extension Decimal {
func rounded(_ roundingMode: NSDecimalNumber.RoundingMode = .down, scale: Int = 0) -> Self {
var result = Self()
var number = self
NSDecimalRound(&result, &number, scale, roundingMode)
return result
}
var whole: Self { rounded( self < 0 ? .up : .down) }
var fraction: Self { self - whole }
var int: Int {
NSDecimalNumber(decimal: whole).intValue
}
}
Just use the description of Decimal, String replacement the NSDecimalNumber to bridge it.
extension Decimal {
var intVal: Int? {
return Int(self.description)
}
}

Error Handling in a Recursive Swift Function [duplicate]

I am making fuction that calculate factorial in swift. like this
func factorial(factorialNumber: UInt64) -> UInt64 {
if factorialNumber == 0 {
return 1
} else {
return factorialNumber * factorial(factorialNumber - 1)
}
}
let x = factorial(20)
this fuction can calculate untill 20.
I think factorial(21) value bigger than UINT64_MAX.
then How to calculate the 21! (21 factorial) in swift?
func factorial(_ n: Int) -> Double {
return (1...n).map(Double.init).reduce(1.0, *)
}
(1...n): We create an array of all the numbers that are involved in the operation (i.e: [1, 2, 3, ...]).
map(Double.init): We change from Int to Double because we can represent bigger numbers with Doubles than with Ints (https://en.wikipedia.org/wiki/Double-precision_floating-point_format). So, we now have the array of all the numbers that are involved in the operation as Doubles (i.e: [1.0, 2.0, 3.0, ...]).
reduce(1.0, *): We start multiplying 1.0 with the first element in the array (1.0*1.0 = 1.0), then the result of that with the next one (1.0*2.0 = 2.0), then the result of that with the next one (2.0*3.0 = 6.0), and so on.
Step 2 is to avoid the overflow issue.
Step 3 is to save us from explicitly defining a variable for keeping track of the partial results.
Unsigned 64 bit integer has a maximum value of 18,446,744,073,709,551,615. While 21! = 51,090,942,171,709,440,000. For this kind of case, you need a Big Integer type. I found a question about Big Integer in Swift. There's a library for Big Integer in that link.
BigInteger equivalent in Swift?
Did you think about using a double perhaps? Or NSDecimalNumber?
Also calling the same function recursively is really bad performance wise.
How about using a loop:
let value = number.intValue - 1
var product = NSDecimalNumber(value: number.intValue)
for i in (1...value).reversed() {
product = product.multiplying(by: NSDecimalNumber(value: i))
}
Here's a function that accepts any type that conforms to the Numeric protocol, which are all builtin number types.
func factorial<N: Numeric>(_ x: N) -> N {
x == 0 ? 1 : x * factorial(x - 1)
}
First we need to declare temp variable of type double so it can hold size of number.
Then we create a function that takes a parameter of type double.
Then we check, if the number equal 0 we can return or do nothing. We have an if condition so we can break the recursion of the function. Finally we return temp, which holds the factorial of given number.
var temp:Double = 1.0
func factorial(x:Double) -> Double{
if(x==0){
//do nothing
}else{
factorial(x: x-1)
temp *= x
}
return temp
}
factorial(x: 21.0)
I make function calculate factorial like this:
func factorialNumber( namber : Int ) -> Int {
var x = 1
for i in 1...namber {
x *= i
}
return x
}
print ( factorialNumber (namber : 5 ))
If you are willing to give up precision you can use a Double to roughly calculate factorials up to 170:
func factorial(_ n: Int) -> Double {
if n == 0 {
return 1
}
var a: Double = 1
for i in 1...n {
a *= Double(i)
}
return a
}
If not, use a big integer library.
func factoruial(_ num:Int) -> Int{
if num == 0 || num == 1{
return 1
}else{
return(num*factoruial(num - 1))
}
}
Using recursion to solve this problem:
func factorial(_ n: UInt) -> UInt {
return n < 2 ? 1 : n*factorial(n - 1)
}
func factorial(a: Int) -> Int {
return a == 1 ? a : a * factorial(a: a - 1)
}
print(factorial(a : 5))
print(factorial(a: 9))

How do I extract any number of digits after the decimal point of a Float and convert it to a String in Swift?

Basically, I have a Float, for example: 3.511054256.
How can I extract n number of digits after the decimal point?
i.e. I'd like to retrieve 0.51, 0.511, 0.5110 or etc.
I know I can easily achieve something like this:
var temp: Float = 3.511054256
var aStr = String(format: "%f", temp)
var arr: [AnyObject] = aStr.componentsSeparatedByString(".")
var tempInt: Int = Int(arr.last as! String)!
However, this gives me 511054. I'd like the option of retrieving any number of digits past the decimal point easily.
For a task I'm doing, I only need to retrieve the first 2 digits after the decimal point, but less restriction would be ideal.
Thanks.
You can specify the number of decimal digits, say N, in your format specifier as %.Nf, e.g., for 5 decimal digits, %.5f.
let temp: Float = 3.511054256
let aStr = String(format: "%.5f", temp).componentsSeparatedByString(".").last ?? "Unexpected"
print(aStr) // 51105
Alternatively, for a more dynamic usage, make use of an NSNumberFormatter:
/* Use NSNumberFormatter to extract specific number
of decimal digits from your float */
func getFractionDigitsFrom(num: Float, inout withFormatter f: NSNumberFormatter,
forNumDigits numDigits: Int) -> String {
f.maximumFractionDigits = numDigits
f.minimumFractionDigits = numDigits
let localeDecSep = f.decimalSeparator
return f.stringFromNumber(num)?.componentsSeparatedByString(localeDecSep).last ?? "Unexpected"
}
/* Example usage */
var temp: Float = 3.511054256
var formatter = NSNumberFormatter()
let aStr = getFractionDigitsFrom(temp, withFormatter: &formatter, forNumDigits: 5)
print(aStr) // 51105
Note that both solutions above will perform rounding; e.g., if var temp: Float = 3.519, then asking for 2 decimal digits will produce "52". If you really intend to treat your float temp purely as a String (with no rounding whatsoever), you could solve this using just String methods, e.g.
/* Just treat input as a string with known format rather than a number */
func getFractionDigitsFrom(num: Float, forNumDigits numDigits: Int) -> String {
guard let foo = String(temp).componentsSeparatedByString(".").last
where foo.characters.count >= numDigits else {
return "Invalid input" // or return nil, for '-> String?' return
}
return foo.substringWithRange(foo.startIndex..<foo.startIndex.advancedBy(numDigits))
}
/* Example usage */
let temp: Float = 3.5199
let aStr = getFractionDigitsFrom(temp, forNumDigits: 2) // 51

strtoul() Function- Swift

I'm trying to create a swift iOS program that converts a number into dec, bin, and hex numbers. I've come across the strtoul function, but don't quite understand how to use it, would someone be able to explain it? Thanks!
The method strtoul is pretty simple to use. You will need also to use String(radix:()) to convert it to the other direction. You can create an extension to convert from hexaToDecimal or from binaryToDecimal as follow:
Usage String(radix:())
extension Int {
var toBinary: String {
return String(self, radix: 2)
}
var toHexa: String {
return String(self, radix: 16)
}
}
Usage strtoul()
extension String {
var hexaToDecimal: Int {
return Int(strtoul(self, nil, 16))
}
var hexaToBinary: String {
return hexaToDecimal.toBinary
}
var binaryToDecimal: Int {
return Int(strtoul(self, nil, 2))
}
var binaryToHexa: String {
return binaryToDecimal.toHexa
}
}
Testing
let myBinFromInt = 255.toBinary // "11111111"
let myhexaFromInt = 255.toHexa // "ff"
let myIntFromHexa = "ff".hexaToDecimal // 255
let myBinFromHexa = "ff".hexaToBinary // "11111111"
let myIntFromBin = "11111111".binaryToDecimal // 255
let myHexaFromBin = "11111111".binaryToHexa // "ff"
The strtoul() function converts the string in str to an unsigned long
value. The conversion is done according to the given base, which must be between 2 and 36 inclusive, or be the special value 0.
Really it sounds like you want to use NSString
From what it sounds like, you want to convert an unsigned integer to decimal, hex and binary.
For example, if you had an integer n:
var st = NSString(format:"%2X", n)
would convert the integer to hexadecimal and store it in the variable st.
//NSString(format:"%2X", 10) would give you 'A' as 10 is A in hex
//NSString(format:"%2X", 17) would give you 11 as 17 is 11 in hex
Binary:
var st = NSString(format:"%u", n)
Decimal (2 decimal places)
var st = NSString(format:"%.02f", n)

Resources