How can I round double values with E - swift

I have a number, like 4.99999999951e+001
I wish I could round this number like 5.000000000e+001
How can I manipulate the double value with out interfering the exponent part.

All double values have an exponent part. Don't get confused by any printout artifacts, especially from the debugger outputs.
Double has round and rounded methods, you can use them like this
let value = 4.99999999951e+001
let rounded = value.rounded() // or other modes, e.g. .rounded(.toNearestOrAwayFromZero)

You could use this Extension for rounding Double values.
extension Double {
func roundTo(places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
Usage:
let v = 3.56789
v.roundTo(places: 1)
I use this in nearly every Project.

try to use round() func
var x = 3.7
x.round() output is // 4

Related

Why does a horizontal line appear in Xcode Playground extension when viewing "Show result"?

I am learning about Swift extensions, and wrote a simple extension to Double in a Playground. Code is below.
extension Double {
func round(to places: Int) -> Double {
let precisionNumber = pow(10, Double(places))
var n = self //self contains the value of the myDouble variable
n = n * precisionNumber
n.round()
n = n / precisionNumber
return n
}
}
var myDouble = 3.14159
myDouble.round(to: 1)
The extension works as planned, however when I press "show result" (the eye icon) in the right column for any line of code in the extension, I see a horizontal line.
Anyone know what this line is supposed to signify? Using Xcode 11.2.1 and Swift 5.
The trouble here is that you have not revealed all of your playground. My guess is that there is more code, where you call your extension again. Perhaps your real code looks something like this:
extension Double {
func round(to places: Int) -> Double {
let precisionNumber = pow(10, Double(places))
var n = self //self contains the value of the myDouble variable
n = n * precisionNumber
n.round()
n = n / precisionNumber
return n
}
}
var myDouble = 3.14159
myDouble.round(to: 1) // once
print(myDouble)
myDouble = myDouble.round(to: 1) // twice; in your case it's probably another value
print(myDouble)
That is a very poor way to write your playground, if your goal is to write and debug your extension, for the very reason you have shown. You have called the extension two times, so what meaningful value can be shown as the "result" of each line of the extension? The playground has to try to show you both "results" from both calls. The only way it can think of to do that is to graph the two results.
That is a downright useful representation, though, when you are deliberately looping or repeating code, because you get at least a sense, through the graph, of how the value changes each time thru the loop.

Round a double down to one decimal place (dropping decimal places)

I want to round a double down to 1 decimal place. For example if I have a double let val = 3.1915 I want to round this down to 3.1. Normal rounding functions will round it to 3.2 but I want to basically just drop the remaining decimal places. What is the best way to do this? Is there a native function for this? I know this is pretty straight forward to do but I want to know what the best way to do this would be where I am not using any kind of workaround or bad practices. This is not a duplicate of other rounding questions because I am not asking about about rounding, I am asking how to drop decimal places.
Similarly, if the value was 3.1215, it would also round to 3.1
Use the function trunc() (which stands for truncate) which will chop away the decimal portion without rounding. Specifically, multiply the Double value by 10, truncate it, then divide by 10 again. Then, to display using 1 decimal place, use String(format:):
let aDouble = 1.15
let truncated = trunc(aDouble * 10) / 10
let string = String(format: "%.1f", truncated
print(string)
(displays "1.1")
or, to process an entire array of sample values:
let floats = stride(from: 1.099, to: 2.0, by: 0.1)
let truncs = floats
.map { trunc($0 * 10) / 10 }
.map { String(format: "%.1f", $0) }
let beforeAndAfter = zip(floats, truncs)
.map { (float: $0.0, truncString: $0.1)}
beforeAndAfter.forEach { print(String(format: "%.3f truncated to 1 place is %#", $0.0, $0.1)) }
Outputs:
1.099 truncated to 1 place is 1.0
1.199 truncated to 1 place is 1.1
1.299 truncated to 1 place is 1.2
1.399 truncated to 1 place is 1.3
1.499 truncated to 1 place is 1.4
1.599 truncated to 1 place is 1.5
1.699 truncated to 1 place is 1.6
1.799 truncated to 1 place is 1.7
1.899 truncated to 1 place is 1.8
1.999 truncated to 1 place is 1.9
By your example I assume you meant you want to Truncate, if so using multiply and casting into Int then Dividing and casting back into Float/Double will do.
Example: 3.1915 -> 3.1
var val = 3.1915
let intVal:Int = Int(val*10)
val = Float(intVal)/10.0
print(val) //3.1
If you want more decimal places simply multiply and divide by 100 or 1000 instead.
Then if for any reason you want to use the round() function there is a overloaded variant that accepts a FloatingPointRoundingRule it will work like:
var val = 3.1915
val*=10 //Determine decimal places
val.round(FloatingPoint.towardZero) // .down is also available which differs in rounding negative numbers.
val*=0.1 //This is a divide by 10
print(val) //3.1
In practical usage I'd suggest making an extension or global function instead of writing this chunk every time. It would look something like:
extension Float {
func trunc(_ decimal:Int) {
var temp = self
let multiplier = powf(10,decimal) //pow() for Double
temp = Float(Int(temp*multiplier))/multiplier //This is actually the first example put into one line
return temp
}
}
And used:
var val = 3.1915
print(val.trunc(1)) //3.1

Swift - rounding numbers

I am trying to round a number in swift, and I found a solution using this:
func roundTo(number: Double, precision: Int) -> Double {
var power: Double = 1
for _ in 1...precision {
power *= 10
}
let rounded = Double(round(power * number)/power)
return rounded
}
I have a model class, lets call it MyObject.
class: My Object {
var preciseNumber: Double?
}
I am fetching a number for example:
var myNumber = 10,0123456789
I use my roundTo function to round it so I have 10,0123456 (7 numbers after the decimal point).
When I print a statement:
print("myNumber rounded: \(roundTo(myNumber, precision: 7))") //10,0123456 as a result. Great!
Then next I want to assing rounded myNumber to my class variable preciseNumber so:
let roundedNumber = roundTo(myNumber, precise: 7)
print("Rounded number is: \(roundedNumber)") // 10,01234567 as result
self.preciseNumber = roundedNumber
print("Precise number is now: \(self.preciseNumber)") // 10,01234599999997 as result
What might be causing this? I want to be as precise as possible.
So it sounds like your issue is being able to compare floating point numbers. The best way to do this is to instead find the degree of precision you need. So rather than just checking numOne == numTwo use something like abs(one - two) <= 0.000001
You can create a Swift operator to handle this for you pretty easily:
// `===` is just used as an example
func === (one: Double, two: Double) -> Bool {
return abs(one - two) <= 0.000001
}
Then you can just check numOne === numTwo and it will use a better floating point equality check.
There is also a power function that will help simplify your rounding function:
let power = pow(10.0, precision)

How to find max value for Double and Float in Swift

Current learning Swift, there are ways to find max and min value for different kind of Integer like Int.max and Int.min.
Is there a way to find max value for Double and Float? Moreover, which document should I refer for this kind of question? I am currently reading Apple's The Swift Programming Language.
As of Swift 3+, you should use:
CGFloat.greatestFiniteMagnitude
Double.greatestFiniteMagnitude
Float.greatestFiniteMagnitude
While there’s no Double.max, it is defined in the C float.h header, which you can access in Swift via import Darwin.
import Darwin
let fmax = FLT_MAX
let dmax = DBL_MAX
These are roughly 3.4 * 10^38 and 1.79 * 10^308 respectively.
But bear in mind it’s not so simple with floating point numbers (it’s never simple with floating point numbers). When holding numbers this large, you lose precision in a similar way to losing precision with very small numbers, so:
let d = DBL_MAX
let e = d - 1.0
let diff = d - e
diff == 0.0 // true
let maxPlusOne = DBL_MAX + 1
maxPlusOne == d // true
let inf = DBL_MAX * 2
// perhaps infinity is the “maximum”
inf == Double.infinity // true
So before you get into some calculations that might possibly brush up against these limits, you should probably read up on floating point. Here and here are probably a good start.
AV's answer is fine, but I find those macros hard to remember and a bit non-obvious, so eventually I made Double.MIN and friends work:
extension Double {
static var MIN = -DBL_MAX
static var MAX_NEG = -DBL_MIN
static var MIN_POS = DBL_MIN
static var MAX = DBL_MAX
}
Don't use lowercase min and max -- those symbols are used in Swift 3.
Just write
let mxFloat = MAXFLOAT
You will get the maximum value of a float in Swift.
Also CGFloat.infinity, Double.infinity or just .infinity can be useful in such situations.
Works with swift 5
public extension Double {
/// Max double value.
static var max: Double {
return Double(greatestFiniteMagnitude)
}
/// Min double value.
static var min: Double {
return Double(-greatestFiniteMagnitude)
}
}

How to round a Double to the nearest Int in swift?

I'm trying to make a calculator of growth rate (Double) that will round the result to the nearest Integer and recalculate from there, as such:
let firstUsers = 10.0
let growth = 0.1
var users = firstUsers
var week = 0
while users < 14 {
println("week \(week) has \(users) users")
users += users * growth
week += 1
}
but I've been unable so far.
EDIT
I kinda did it like so:
var firstUsers = 10.0
let growth = 0.1
var users:Int = Int(firstUsers)
var week = 0
while users <= 14 {
println("week \(week) has \(users) users")
firstUsers += firstUsers * growth
users = Int(firstUsers)
week += 1
}
Although I don't mind that it is always rounding down, I don't like it because firstUsers had to become a variable and change throughout the program (in order to make the next calculation), which I don't want it to happen.
There is a round available in the Foundation library (it's actually in Darwin, but Foundation imports Darwin and most of the time you'll want to use Foundation instead of using Darwin directly).
import Foundation
users = round(users)
Running your code in a playground and then calling:
print(round(users))
Outputs:
15.0
round() always rounds up when the decimal place is >= .5 and down when it's < .5 (standard rounding). You can use floor() to force rounding down, and ceil() to force rounding up.
If you need to round to a specific place, then you multiply by pow(10.0, number of places), round, and then divide by pow(10, number of places):
Round to 2 decimal places:
let numberOfPlaces = 2.0
let multiplier = pow(10.0, numberOfPlaces)
let num = 10.12345
let rounded = round(num * multiplier) / multiplier
print(rounded)
Outputs:
10.12
Note: Due to the way floating point math works, rounded may not always be perfectly accurate. It's best to think of it more of an approximation of rounding. If you're doing this for display purposes, it's better to use string formatting to format the number rather than using math to round it.
To round a double to the nearest integer, just use round().
var x = 3.7
x.round() // x = 4.0
If you don't want to modify the original value, then use rounded():
let x = 3.7
let y = x.rounded() // y = 4.0. x = 3.7
As one might expect (or might not), a number like 3.5 is rounded up and a number like -3.5 is rounded down. If you need different rounding behavior than that, you can use one of the rounding rules. For example:
var x = 3.7
x.round(.towardZero) // 3.0
If you need an actual Int then just cast it to one (but only if you are certain that the Double won't be greater than Int.max):
let myInt = Int(myDouble.rounded())
Notes
This answer is completely rewritten. My old answer dealt with the C math functions like round, lround, floor, and ceil. However, now that Swift has this functionality built in, I can no longer recommend using those functions. Thanks to #dfri for pointing this out to me. Check out #dfri's excellent answer here. I also did something similar for rounding a CGFloat.
Swift 3 & 4 - making use of the rounded(_:) method as blueprinted in the FloatingPoint protocol
The FloatingPoint protocol (to which e.g. Double and Float conforms) blueprints the rounded(_:) method
func rounded(_ rule: FloatingPointRoundingRule) -> Self
Where FloatingPointRoundingRule is an enum enumerating a number of different rounding rules:
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.
We make use of similar examples to the ones from #Suragch's excellent answer to show these different rounding options in practice.
.awayFromZero
Round to the closest allowed value whose magnitude is greater than or equal to that of the source; no direct equivalent among the C functions, as this uses, conditionally on sign of self, ceil or floor, for positive and negative values of self, respectively.
3.000.rounded(.awayFromZero) // 3.0
3.001.rounded(.awayFromZero) // 4.0
3.999.rounded(.awayFromZero) // 4.0
(-3.000).rounded(.awayFromZero) // -3.0
(-3.001).rounded(.awayFromZero) // -4.0
(-3.999).rounded(.awayFromZero) // -4.0
.down
Equivalent to the C floor function.
3.000.rounded(.down) // 3.0
3.001.rounded(.down) // 3.0
3.999.rounded(.down) // 3.0
(-3.000).rounded(.down) // -3.0
(-3.001).rounded(.down) // -4.0
(-3.999).rounded(.down) // -4.0
.toNearestOrAwayFromZero
Equivalent to the C round function.
3.000.rounded(.toNearestOrAwayFromZero) // 3.0
3.001.rounded(.toNearestOrAwayFromZero) // 3.0
3.499.rounded(.toNearestOrAwayFromZero) // 3.0
3.500.rounded(.toNearestOrAwayFromZero) // 4.0
3.999.rounded(.toNearestOrAwayFromZero) // 4.0
(-3.000).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.001).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.499).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.500).rounded(.toNearestOrAwayFromZero) // -4.0
(-3.999).rounded(.toNearestOrAwayFromZero) // -4.0
This rounding rule can also be accessed using the zero argument rounded() method.
3.000.rounded() // 3.0
// ...
(-3.000).rounded() // -3.0
// ...
.toNearestOrEven
Round to the closest allowed value; if two values are equally close, the even one is chosen; equivalent to the C rint (/very similar to nearbyint) function.
3.499.rounded(.toNearestOrEven) // 3.0
3.500.rounded(.toNearestOrEven) // 4.0 (up to even)
3.501.rounded(.toNearestOrEven) // 4.0
4.499.rounded(.toNearestOrEven) // 4.0
4.500.rounded(.toNearestOrEven) // 4.0 (down to even)
4.501.rounded(.toNearestOrEven) // 5.0 (up to nearest)
.towardZero
Equivalent to the C trunc function.
3.000.rounded(.towardZero) // 3.0
3.001.rounded(.towardZero) // 3.0
3.999.rounded(.towardZero) // 3.0
(-3.000).rounded(.towardZero) // 3.0
(-3.001).rounded(.towardZero) // 3.0
(-3.999).rounded(.towardZero) // 3.0
If the purpose of the rounding is to prepare to work with an integer (e.g. using Int by FloatPoint initialization after rounding), we might simply make use of the fact that when initializing an Int using a Double (or Float etc), the decimal part will be truncated away.
Int(3.000) // 3
Int(3.001) // 3
Int(3.999) // 3
Int(-3.000) // -3
Int(-3.001) // -3
Int(-3.999) // -3
.up
Equivalent to the C ceil function.
3.000.rounded(.up) // 3.0
3.001.rounded(.up) // 4.0
3.999.rounded(.up) // 4.0
(-3.000).rounded(.up) // 3.0
(-3.001).rounded(.up) // 3.0
(-3.999).rounded(.up) // 3.0
Addendum: visiting the source code for FloatingPoint to verify the C functions equivalence to the different FloatingPointRoundingRule rules
If we'd like, we can take a look at the source code for FloatingPoint protocol to directly see the C function equivalents to the public FloatingPointRoundingRule rules.
From swift/stdlib/public/core/FloatingPoint.swift.gyb we see that the default implementation of the rounded(_:) method makes us of the mutating round(_:) method:
public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
var lhs = self
lhs.round(rule)
return lhs
}
From swift/stdlib/public/core/FloatingPointTypes.swift.gyb we find the default implementation of round(_:), in which the equivalence between the FloatingPointRoundingRule rules and the C rounding functions is apparent:
public mutating func round(_ rule: FloatingPointRoundingRule) {
switch rule {
case .toNearestOrAwayFromZero:
_value = Builtin.int_round_FPIEEE${bits}(_value)
case .toNearestOrEven:
_value = Builtin.int_rint_FPIEEE${bits}(_value)
case .towardZero:
_value = Builtin.int_trunc_FPIEEE${bits}(_value)
case .awayFromZero:
if sign == .minus {
_value = Builtin.int_floor_FPIEEE${bits}(_value)
}
else {
_value = Builtin.int_ceil_FPIEEE${bits}(_value)
}
case .up:
_value = Builtin.int_ceil_FPIEEE${bits}(_value)
case .down:
_value = Builtin.int_floor_FPIEEE${bits}(_value)
}
}
**In Swift**
var a = 14.123456789
var b = 14.123456789
var c = 14.123456789
var d = 14.123456789
var e = 14.123456789
var f = 14.123456789
a.rounded(.up) //15
b.rounded(.down) //14
c.rounded(.awayFromZero) //15
d.rounded(.towardZero) //14
e.rounded(.toNearestOrAwayFromZero) //14
f.rounded(.toNearestOrEven) //14
Swift 3:
If you want to round to a certain digit number e.g. 5.678434 -> 5.68 you can just combine the round() or roundf() function with a multiplication:
let value:Float = 5.678434
let roundedValue = roundf(value * 100) / 100
print(roundedValue) //5.68
You can also extend FloatingPoint in Swift 3 as follow:
extension FloatingPoint {
func rounded(to n: Int) -> Self {
let n = Self(n)
return (self / n).rounded() * n
}
}
324.0.rounded(to: 5) // 325
Swift 3
var myNum = 8.09
myNum.rounded() // result = 8 and leaves myNum unmodified
A very easy solution worked for me:
if (62 % 50 != 0) {
var number = 62 / 50 + 1 // adding 1 is doing the actual "round up"
}
number contains value 2
This is the easiest way I came across
let weightValue = 143.69
print("Rounded off weight value = \(Int(weightValue))")
Alternate method:
print("Rounded off weight value = \((String(format: "%.0f", sender.value)))")