I would like to round a Double to the closest multiple of 10.
For example if the number is 8.0 then round to 10.
If the number is 2.0 round it to 0.
How can I do that?
You can use the round() function (which rounds a floating point number
to the nearest integral value) and apply a "scale factor" of 10:
func roundToTens(x : Double) -> Int {
return 10 * Int(round(x / 10.0))
}
Example usage:
print(roundToTens(4.9)) // 0
print(roundToTens(15.1)) // 20
In the second example, 15.1 is divided by ten (1.51), rounded (2.0),
converted to an integer (2) and multiplied by 10 again (20).
Swift 3:
func roundToTens(_ x : Double) -> Int {
return 10 * Int((x / 10.0).rounded())
}
Alternatively:
func roundToTens(_ x : Double) -> Int {
return 10 * lrint(x / 10.0)
}
defining the rounding function as
import Foundation
func round(_ value: Double, toNearest: Double) -> Double {
return round(value / toNearest) * toNearest
}
gives you more general and flexible way how to do it
let r0 = round(1.27, toNearest: 0.25) // 1.25
let r1 = round(325, toNearest: 10) // 330.0
let r3 = round(.pi, toNearest: 0.0001) // 3.1416
UPDATE
more generic definitions
func round<T:BinaryFloatingPoint>(_ value:T, toNearest:T) -> T {
return round(value / toNearest) * toNearest
}
func round<T:BinaryInteger>(_ value:T, toNearest:T) -> T {
return T(round(Double(value), toNearest:Double(toNearest)))
}
and usage
let A = round(-13.16, toNearest: 0.25)
let B = round(8, toNearest: 3.0)
let C = round(8, toNearest: 5)
print(A, type(of: A))
print(B, type(of: B))
print(C, type(of: C))
prints
-13.25 Double
9.0 Double
10 Int
You can also extend FloatingPoint protocol and add an option to choose the rounding rule:
extension FloatingPoint {
func rounded(to value: Self, roundingRule: FloatingPointRoundingRule = .toNearestOrAwayFromZero) -> Self {
(self / value).rounded(roundingRule) * value
}
}
let value = 325.0
value.rounded(to: 10) // 330 (default rounding mode toNearestOrAwayFromZero)
value.rounded(to: 10, roundingRule: .down) // 320
In Swift 3.0 it is
10 * Int(round(Double(ratio / 10)))
Extension for rounding to any number !
extension Int{
func rounding(nearest:Float) -> Int{
return Int(nearest * round(Float(self)/nearest))
}
}
Nice extension for BinaryFloatingPoint in swift:
extension BinaryFloatingPoint{
func roundToTens() -> Int{
return 10 * Int(Darwin.round(self / 10.0))
}
func roundToHundreds() -> Int{
return 100 * Int(Darwin.round(self / 100.0))
}
}
extension Double {
var roundToTens: Double {
let divideByTen = self / 10
let multiByTen = (ceil(divideByTen) * 10)
return multiByTen
}
}
usage:
36. roundToTens
Related
This doesn't compile because Initializer 'init(_:)' requires that 'Number' conform to 'BinaryInteger'
struct Percentage<Number: Numeric> {
let value: Number
let total: Number
var percentage: Double {
Double(value) / Double(total)
}
}
Does anyone have a nice solution?
To give some context to the problem from real life: I'm coding a SwiftUI app, that has a CircularProgress-view. I would like to use the same CircularProgress-view with different number types and to be able to show the current value in proportion to min and max. To do that, I need to solve the problem above.
The main issue is that Numeric doesn't support generic divisions. One possible solution is to provide multiple generic methods to support different protocols (Integer/FloatingPoint) and Decimal as well:
extension Decimal {
var number: NSDecimalNumber { self as NSDecimalNumber }
var double: Double { number.doubleValue }
}
struct Percentage<T: Numeric> {
let value: T
let total: T
func percentage<F: BinaryFloatingPoint>() -> F where T: BinaryFloatingPoint {
F(value) / F(total)
}
func percentage<F: BinaryFloatingPoint>() -> F where T: BinaryInteger {
F(value) / F(total)
}
func percentage<F: BinaryFloatingPoint>() -> F where T == Decimal {
F(value.double) / F(total.double)
}
func percentage() -> Decimal where T == Decimal {
value / total
}
}
let percentageInt = Percentage<Int>(value: 10, total: 100)
let result1: Double = percentageInt.percentage() // 0.1
let percentageDouble = Percentage<Double>(value: 10, total: 100)
let result2: Double = percentageDouble.percentage() // 0.1
let result3: CGFloat = percentageDouble.percentage() // 0.1
let percentageDecimal = Percentage<Decimal>(value: 10, total: 100)
let result4 = percentageDecimal.percentage() // 0.1 decimal
let result5: Double = percentageDecimal.percentage() // 0.1
You can create extensions on Percentage where you restrict Number to BinaryInteger and FloatingPoint to be able to use the / operator.
struct Percentage<Number: Numeric> {
let value: Number
let total: Number
}
extension Percentage where Number: BinaryInteger {
var percentage: Double {
Double(value) / Double(total)
}
}
extension Percentage where Number: FloatingPoint {
var percentage: Number {
value / total
}
}
Percentage(value: 15, total: 60).percentage // 25.0
Percentage(value: 1.5, total: 3.0).percentage // 50.0
I want to specify my (slider) double to 2 decimals but xcode won't let me do that:
return (Double(pris, specifier: "%.2f"))
And i don't want to convert it into a string and then format it because numbers like 600000000 are then unreadable.
I have tried solutions like :
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
}
}
let b: Double = Double(600000000.376)
let result = Double(round(100*b)/100)
print(result) // prints 600000000.38
This should do what you need:
extension Double {
func roundedTo(places: Int) -> Double {
let conversion = pow(10.0, Double(places))
return (self * conversion).rounded() / conversion
}
}
print(10.125.roundedTo(places: 2)) // prints 10.13
print(10.124.roundedTo(places: 2)) // prints 10.12
The simple solution was to remove the (Double) before the calculation.
return (Double(pris, specifier: "%.2f"))
should be only
pris, specifier: "%.2f")
I've been researching the concept of encapsulation and found some decent threads about the topic like this one and this one. But I haven't been able to find an answer to a particular question I have. I'll use an example in Swift.
Say you have an object that is of type RoadTrip:
class RoadTrip() {
private var duration: Double
private var totalMiles: Double
private var gallonsOfFuel: Double
var averageMilesPerGallon: Double
}
Now let's say the app is going to calculate the averageMilesPerGallon which is the only public property:
func calculateAverageMilePerGallon() -> Double {
let mpg = totalMiles / gallonsOfFuel
return mpg
}
Should the calculation of average miles per gallon be a private method of the RoadTrip object that executes and updates its averageMilesPerGallon or would it be acceptable to have the calculation performed by another method in a separate utility class that then updates the averageMilesPerGallon property of the RoadTrip object using a mutator method that will set the value?
EDIT: Here's my single class that contains my app's basic calculations. I approached it this way based on what I learned in the Stanford course on iTunes, but I'm beginning to think in my case I should move much of this to my LiftEvent class:
infix operator ^^ { }
func ^^ (radix: Double, power: Double) -> Double {
return Double(pow(Double(radix), Double(power)))
}
class CalculatorBrain: NSObject {
var weightLifted: Double?
var repetitions: Double?
var oneRepMax: Double?
let dataManager = LiftEventDataManager()
func calculateOneRepMax(weightLifted: Double, repetitions: Int ) -> Double {
let preferredFormulaID = UserDefaultsManager.sharedInstance.preferredFormula!
let formulas = dataManager.fetchSelectableFormulas()
let formulaName = formulas[preferredFormulaID].formulaName
switch formulaName {
case "Epley":
oneRepMax = weightLifted * (1 + Double(repetitions)/30.0)
return oneRepMax!
case "Baechle":
oneRepMax = weightLifted * (36/(37 - Double(repetitions)))
return oneRepMax!
case "Brzychi":
oneRepMax = weightLifted * ( 1 + ( 0.033 * Double(repetitions)))
return oneRepMax!
case "Lander":
oneRepMax = 100 * weightLifted / (101.3 - (2.67123 * Double(repetitions)))
return oneRepMax!
case "Lombardi":
oneRepMax = weightLifted * (Double(repetitions) ^^ 0.10)
return oneRepMax!
case "Mayhew":
oneRepMax = 100 * weightLifted / (52.2 + (41.9 * (2.71828 ^^ (-0.055 * Double(repetitions)))))
return oneRepMax!
case "O'Conner":
oneRepMax = weightLifted * (1 + 0.025 * Double(repetitions))
return oneRepMax!
default:
return 0.0
}
}
private func calculatePercentOfWeight(maxWeight: Double, percent: Double) -> Double {
return maxWeight * percent
}
func calculateWeightPercentages(maxWeight: String) -> [Int: Double] {
let weightPercentages = [1.0, 0.95, 0.90, 0.85, 0.80, 0.75, 0.70, 0.65, 0.60, 0.55, 0.50, 0.45, 0.40, 0.35, 0.30, 0.25]
var percentages = [Int: Double]()
for percent in weightPercentages {
let integerPercent = Int(percent * 100)
percentages[integerPercent] = calculatePercentOfWeight(Double(maxWeight)!, percent: percent)
}
return percentages
}
func convertBetweenUnits(fromUnit: Int, toUnit: Int, value: Double) -> Double {
let units = dataManager.fetchUnits()
let from = units[fromUnit].conversionRatio as Double
let to = units[toUnit].conversionRatio as Double
let result = Double(value * to / from)
return result
}
}
I think this is the ideal use-case for a computed property:
class RoadTrip {
private let duration: Double
private let totalMiles: Double
private let gallonsOfFuel: Double
private var averageMilesPerGallon: Double {
return totalMiles / gallonsOfFuel
}
}
I have been working on learning something about the Accelerate framework and am writing a Vector class to go along with my learning experience. I decided I needed to implement the Sequence protocol and after several false starts and much searching for relevant information to my problem finally came up with a solution that seems to work. Not sure if my solution is proper or not and would like comment if there are better ways to do this. Current code is a bit long but not super long so I will post it here.
import Foundation
import Accelerate
public class Vdsp{
public class VectorD: Sequence, IteratorProtocol {
var vindex = 0
public func makeIterator() -> Double? {
return next()
}
public func next() -> Double? {
let nextIndex = self.vindex * self.s + self.o
guard self.vindex < self.l && nextIndex < self.count
else {
self.vindex = 0
return nil
}
self.vindex += 1
return self.data[nextIndex]
}
public let count : Int
fileprivate var l: Int
fileprivate var o: Int
fileprivate var s: Int
public var length : Int {
get {
return self.l
}
set (value){
let l = (value - 1) * self.s + self.o
if l < 0 || l >= self.count {
preconditionFailure("length exceeds vector boundary")
}
self.l = value
}
}
public var stride : Int {
get {
return self.s
}
set (value){
let l = (self.l - 1) * value + self.o
if l < 0 || l >= self.count {
preconditionFailure("stride will cause vector to exceed vector boundary")
}
self.s = value
}
}
public var offset : Int {
get {
return self.o
}
set (value){
let l = (self.l - 1) * self.s + value
if l < 0 || l >= self.count {
preconditionFailure("stride will cause vector to exceed vector boundary")
}
self.o = value
}
}
// length * stride + offset >= 0 and <= count
public var data : Array<Double>
public init(length: Int){
self.count = length
self.l = length
self.s = 1
self.o = 0
data = Array(repeating: 0.0, count: count)
}
// MARK: - Utility functions
public var empty : VectorD { // Create a new vector unit stride, zero offset
get{
return VectorD(length: length)
}
}
public func display(decimals: Int) -> String {
let fmt = String("%0." + String(decimals) + "f\n")
var aString = ""
for i in 0..<length {
aString += String(format: fmt!, self.data[offset + i * stride])
}
return aString
}
// MARK: - Subscripts and Operators
public subscript(index: Int) -> Double {
get {
if index > length {
preconditionFailure("index \(index) out of bounds")
} else {
return data[self.offset + index * self.stride]
}
}
set(newValue) {
if index > self.length {
preconditionFailure("index \(index) out of bounds")
} else {
self.data[self.offset + index * self.stride] = newValue
}
}
}
public static func + (left: VectorD, right: VectorD) -> VectorD {
return Vdsp.add(left, right)
}
public static func + (left: Double, right: VectorD) -> VectorD {
return Vdsp.add(left, right)
}
public static func + (left: VectorD, right: Double) -> VectorD {
return Vdsp.add(right, left)
}
public static func * (left: VectorD, right: VectorD) -> VectorD {
return Vdsp.mul(left, right)
}
public static func * (left: Double, right: VectorD) -> VectorD {
return Vdsp.mul(left, right)
}
public static func * (left: VectorD, right: Double) -> VectorD {
return Vdsp.mul(right, left)
}
// MARK: - vDSP routines as methods of VectorD
public func fill(value: Double){
var v = value
vDSP_vfillD(&v, &data + offset, stride, vDSP_Length(length))
}
public func ramp(start: Double, increment: Double){
var s = start
var i = increment
vDSP_vrampD(&s, &i, &data + offset, stride, vDSP_Length(length))
}
public var sumval : Double {
get {
var s : Double = 0.0
vDSP_sveD(&data + offset, stride, &s, vDSP_Length(length))
return s
}
}
}
// MARK: - vDSP routines as class functions of Vdsp
public static func add(_ v1: VectorD, _ v2: VectorD) -> VectorD {
let v3 = v1.empty
vDSP_vaddD( &v1.data + v1.offset, v1.stride, &v2.data + v2.offset , v2.stride, &v3.data, 1, vDSP_Length(v3.length))
return v3
}
public static func add(_ s: Double, _ v: VectorD) -> VectorD {
var sdta = s
let r = v.empty
vDSP_vsaddD( &v.data + v.offset, v.stride, &sdta, &r.data, 1, vDSP_Length(v.length))
return r
}
public static func mul(_ v1: VectorD, _ v2: VectorD) -> VectorD {
let v3 = v1.empty
vDSP_vmulD( &v1.data + v1.offset, v1.stride, &v2.data + v2.offset, v2.stride, &v3.data, 1, vDSP_Length(v3.length))
return v3
}
public static func mul(_ s: Double, _ v: VectorD) -> VectorD {
var sdta = s
let r = v.empty
vDSP_vsmulD( &v.data + v.offset, v.stride, &sdta, &r.data, 1, vDSP_Length(v.length))
return r
}
}
I am exercising this with
//: Playground for Accelerate
import UIKit
let V = Vdsp.VectorD(length: 10);V.ramp(start: 0.1, increment: 0.2)
print("Vector V after ramp(0.1,0.2)");print(V.display(decimals: 3))
V.length = 4
V.stride = 2
V.offset = 1
print("Vector V after attribute modification")
print(V.display(decimals: 3))
let Q = V.empty
Q.ramp(start: 1.0, increment: 1.0)
print("Vector Q after ramp(1.0,1.0)");print(Q.display(decimals: 3))
print("V * Q"); var R = V * Q
for i in 0..<V.length {
print("\(V[i]) * \(Q[i]) = \(R[i])")
}
R = V + Q; print("V + Q = R")
for i in 0..<V.length {
print("\(V[i]) + \(Q[i]) = \(R[i])")
}
print("\n")
for item in V.data {
print(item)
}
print("\n")
for item in V {
print(item)
}
print("\n")
V.offset = 3
for item in V {
print(item)
}
and I seem to get the proper output. The Sequence protocol is in the first few lines of the VectorD class.
Your implementation of the Sequence protocol is not correct.
First, your makeIterator() method is not used at all because it has the wrong signature,
it does not return an Iterator. (You can remove that function from your code without changing anything.) Iterating over the vector elements works
because there is a default implementation of makeIterator() for all
iterators which are declared to conform to Sequence.
Second, your next() method uses an instance variable vindex
which is reset to zero after reaching the end of the iteration.
In other words, it is assumed that all elements are retrieved before
iterating the same vector again. This gives the unexpected output:
let V = Vdsp.VectorD(length: 10)
V.ramp(start: 1.0, increment: 1.0)
print(Array(V.prefix(4))) // [1.0, 2.0, 3.0, 4.0]
print(Array(V.prefix(4))) // [5.0, 6.0, 7.0, 8.0]
print(Array(V.prefix(4))) // [9.0, 10.0]
print(Array(V.prefix(4))) // [1.0, 2.0, 3.0, 4.0]
Here is a possible implementation of the Sequence protocol:
public class VectorD: Sequence {
public func makeIterator() -> AnyIterator<Double> {
var vindex = 0
return AnyIterator {
let nextIndex = vindex * self.s + self.o
guard vindex < self.l && nextIndex < self.count else {
return nil
}
vindex += 1
return self.data[nextIndex]
}
}
// ...
}
Note that vindex is now a local variable of makeIterator()
and captured by the closure. Calling makeIterator() again
will start from the beginning even if the previous iteration did
not retrieve all elements:
print(Array(V.prefix(4))) // [1.0, 2.0, 3.0, 4.0]
print(Array(V.prefix(4))) // [1.0, 2.0, 3.0, 4.0]
Another possible implementation would be
public class VectorD: Sequence {
public func makeIterator() -> AnyIterator<Double> {
let upperBound = Swift.min(count, o + l * s)
let it = Swift.stride(from: o, to: upperBound, by: s)
.lazy.map { self.data[$0] }.makeIterator()
return AnyIterator(it)
}
// ...
}
using the stride() method from the Swift standard
library.
Does anyone know how to get the sum of all the digits in a number in Swift?
For example using the number 845 would result in 17
update: Swift 5 or later We can use then new Character property wholeNumberValue:
let string = "845"
let sum = string.compactMap{$0.wholeNumberValue}.reduce(0, +)
print(sum) // 17
let integer = 845
let sumInt = String(integer).compactMap{$0.wholeNumberValue}.reduce(0, +)
print(sumInt) // 17
Here is a solution that uses simple integer arithmetic only:
func digitSum(var n : Int) -> Int {
var sum = 0
while n > 0 {
sum += n % 10 // Add least significant digit ...
n /= 10 // ... and remove it from the number.
}
return sum
}
println(digitSum(845)) // 17
Update for Swift 3/4:
func digitSum(_ n : Int) -> Int {
var n = n
var sum = 0
while n > 0 {
sum += n % 10 // Add least significant digit ...
n /= 10 // ... and remove it from the number.
}
return sum
}
print(digitSum(845)) // 17
Another implementation, just for fun:
func digitSum(_ n : Int) -> Int {
return sequence(state: n) { (n: inout Int) -> Int? in
defer { n /= 10 }
return n > 0 ? n % 10 : nil
}.reduce(0, +)
}
The recursive solution in Swift 3!
func digitSum(of number: Int) -> Int {
if(number < 10) {
return number
} else {
return (number % 10) + digitSum(of: (number/10))
}
}
For the sake of completeness, and for those who would like to see or understand a math-based approach, here's a real-number function based technique ported to Swift.
This is not the most efficient way to tally the digits of an integer in Swift. I don't recommend using it. I would personally use #LeoLDbus map/reduce answer to the question, because it is so cool and illustrates a powerful set of Swift features yet short, or #MartinR integer mod/divide answer, due to its utter simplicity and relative speed of integer arithmetic .
Cocoa and UIKit have the requisite math methods, so you'll probably need to import one of those packages.
func sumDigits(var i : Int) -> Int {
var sum = 0
var nDigits = floor(log10(Double(i))) + 1
for var r = nDigits; r > 0; r-- {
var p = pow(10, r - 1)
var d = floor(Double(i) / p)
sum += Int(d)
i -= Int(d * p)
}
return sum
}
for swift4, try below function:
func sumDigits(num: Int) -> Int {
return String(num).compactMap { Int(String($0)) }.reduce(0, +)
}
Split it into two pieces:
digits
public extension UnsignedInteger {
/// The digits that make up this number.
/// - Parameter radix: The base the result will use.
func digits(radix: Self = 10) -> [Self] {
sequence(state: self) { quotient in
guard quotient > 0
else { return nil }
let division = quotient.quotientAndRemainder(dividingBy: radix)
quotient = division.quotient
return division.remainder
}
.reversed()
}
}
XCTAssertEqual(
(867_5309 as UInt).digits(),
[8,6,7, 5,3,0,9]
)
XCTAssertEqual(
(0x00_F0 as UInt).digits(radix: 0b10),
[1,1,1,1, 0,0,0,0]
)
XCTAssertEqual(
(0xA0_B1_C2_D3_E4_F5 as UInt).digits(radix: 0x10),
[10,0, 11,1, 12,2, 13,3, 14,4, 15,5]
)
XCTAssertEqual(
(0o00707 as UInt).digits(radix: 0o10),
[0b111, 0, 0b111]
)
sum
public extension Sequence where Element: AdditiveArithmetic {
var sum: Element? { reduce(+) }
}
public extension Sequence {
/// The first element of the sequence.
/// - Note: `nil` if the sequence is empty.
var first: Element? {
var iterator = makeIterator()
return iterator.next()
}
/// - Returns: `nil` If the sequence has no elements, instead of an "initial result".
func reduce(
_ getNextPartialResult: (Element, Element) throws -> Element
) rethrows -> Element? {
guard let first = first
else { return nil }
return try dropFirst().reduce(first, getNextPartialResult)
}
}
XCTAssertEqual([1, 2, 3].sum, 6)
XCTAssertEqual([0.5, 1, 1.5].sum, 3)
XCTAssertNil([CGFloat]().sum)