Làm tròn một giá trị gấp đôi đến x số vị trí thập phân trong swift


395

Ai đó có thể cho tôi biết cách làm tròn một giá trị gấp đôi đến x số vị trí thập phân trong Swift không?

Tôi có:

var totalWorkTimeInHours = (totalWorkTime/60/60)

Với totalWorkTimeviệc là một NSTimeInterval (gấp đôi) trong giây.

totalWorkTimeInHours sẽ cho tôi số giờ, nhưng nó cho tôi lượng thời gian với một con số chính xác dài như vậy, ví dụ 1.543240952039 ......

Làm thế nào để tôi làm tròn số này xuống, nói, 1.543 khi tôi in totalWorkTimeInHours?


1
Xem câu trả lời của tôi để tìm lên đến 9 cách khác nhau để làm tròn một đôi sử dụng Darwin round(_:), Double round(), NSStringkhởi tạo, Stringkhởi tạo, NumberFormatter, mở rộng đôi hoặc thậm chí NSDecimalNumberDecimal.
Imanou Petit

@Rounded, trình bao bọc thuộc tính 5.1 nhanh chóng: gist.github.com/abhijithpp/1cc41b41a5d1c8f007da90f20bc0c65f
Abhijith

Câu trả lời:


389

Bạn có thể sử dụng roundchức năng của Swift để thực hiện điều này.

Để làm tròn a Doublevới 3 chữ số chính xác, đầu tiên nhân nó với 1000, làm tròn nó và chia kết quả làm tròn cho 1000:

let x = 1.23556789
let y = Double(round(1000*x)/1000)
print(y)  // 1.236

Khác với bất kỳ loại printf(...)hoặc String(format: ...)giải pháp nào, kết quả của hoạt động này vẫn là loại Double.

EDIT:
Liên quan đến các ý kiến ​​đôi khi nó không hoạt động, xin vui lòng đọc này:

Những gì mọi lập trình viên nên biết về số học dấu phẩy động


Vì một số lý do, nó không giúp ích gì cả {"($ 0)"})
Fawkes

29
Không hoạt động cho tôi trong sân chơi: let rate = 9.94999999999; Double(round(rate * 100) / 100);Đầu ra: 9.94999999999, 9.949999999999999Chỉ hoạt động để in nhưng làm cách nào tôi có thể gán nó cho biến?
Alexander Yakovlev

Bạn nên sử dụng Decimal cho điều này, không phải đôi.
csotiriou

13
"Điều mà mọi nhà khoa học máy tính nên biết về số học dấu phẩy động" dài 73 trang. TL, DR là gì? :)
JaredH

1
@HardikDG Tôi không nhớ, xin lỗi :-)
Alexander Yakovlev

431

Tiện ích mở rộng cho Swift 2

Một giải pháp tổng quát hơn là tiện ích mở rộng sau, hoạt động với 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
    }
}


Tiện ích mở rộng cho Swift 3

Trong Swift 3 roundđược thay thế bằng 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
    }
}


Ví dụ trả về Double được làm tròn đến 4 chữ số thập phân:

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

17
Bản chất của Swift's Double dường như là không chính xác - do cách nó được lưu trữ / truy cập trong hệ nhị phân, ngay cả khi sử dụng chức năng làm tròn này sẽ không trả về một số được làm tròn đến 3 chữ số thập phân: ví dụ: round(8.46 * pow(10.0, 3.0)) / pow(10.0, 3.0)trả về 8.460000000000001. Làm tương tự với Float, ít nhất là trong kịch bản này , trên thực tế dường như có tác dụng: round(Float(8.46) * pow(10.0, 3.0)) / pow(10.0, 3.0)sản lượng 8.46. Chỉ cần một cái gì đó đáng chú ý.
Ben Saufley

2
Thật không may, điều này không còn hoạt động trong Swift 3 nữa, tôi đang gặp lỗi nàyNo '*' candidates produce the expected contextual result type 'FloatingPointRoundingRule'
koen

2
Tôi đã cập nhật giải pháp và thêm tiện ích mở rộng cho Swift 3.
Sebastian

2
Để nhanh hơn 3 ... bạn nên thay đổi cho func được làm tròn (thay thế vị trí: Int) -> Double
FouZ

2
@BenSaufley Nhưng nó cũng không hoạt động nếu bạn nhập 98,68. Trong trường hợp này, tôi nhận được 98.6800003
Alexander Khitev

340

Làm thế nào để tôi làm tròn số này xuống, nói, 1.543 khi tôi in totalWorkTimeInHours ?

Để làm tròn totalWorkTimeInHoursđến 3 chữ số để in, hãy sử dụng hàm Stringtạo có một formatchuỗi:

print(String(format: "%.3f", totalWorkTimeInHours))

24
Đó là cắt ngắn, không làm tròn
Nhãn cầu

33
@Eyeball: Thật ra, nó LÀM tròn. Đó là hành vi tương tự như chức năng printf C, làm tròn đến các chữ số được yêu cầu. Vì vậy, String(format: "%.3f", 1.23489)bản in1.235
zisoft 7/12/14

6
Người đăng ban đầu đang tìm kiếm một giá trị số để sử dụng, không phải là một chuỗi để hiển thị.
pr1001

17
@ pr1001, có lẽ là như vậy, nhưng điều đó không rõ ràng vào thời điểm đó và 46 người khác đã tìm thấy câu trả lời của tôi hữu ích. Stack Overflow không chỉ giúp OP.
vacawama

3
lẻ, điều này trở lại 0,00 mỗi lần.
Eric H

254

Với Swift 5, theo nhu cầu của bạn, bạn có thể chọn một trong 9 kiểu sau để có kết quả làm tròn từ a Double.


# 1. Sử dụng FloatingPoint rounded()phương pháp

Trong trường hợp đơn giản nhất, bạn có thể sử dụng Double rounded()phương pháp.

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. Sử dụng FloatingPoint rounded(_:)phương pháp

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. Sử dụng roundchức năng Darwin

Foundation cung cấp một roundchức năng thông qua 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. Sử dụng một Doublephương thức tùy chỉnh mở rộng được xây dựng với Darwin roundpowcác chức năng

Nếu bạn muốn lặp lại thao tác trước đó nhiều lần, tái cấu trúc mã của bạn có thể là một ý tưởng tốt.

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. Sử dụng NSDecimalNumber rounding(accordingToBehavior:)phương pháp

Nếu cần, NSDecimalNumbercung cấp một giải pháp dài dòng nhưng mạnh mẽ để làm tròn số thập phân.

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. Sử dụng NSDecimalRound(_:_:_:_:)chức năng

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. Sử dụng bộ NSString init(format:arguments:)khởi tạo

Nếu bạn muốn trả về một NSStringtừ hoạt động làm tròn của mình, sử dụng bộ NSStringkhởi tạo là một giải pháp đơn giản nhưng hiệu quả.

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

#số 8. Sử dụng bộ String init(format:_:)khởi tạo

StringKiểu của Swift được bắc cầu bằng NSStringlớp Foundation . Do đó, bạn có thể sử dụng mã sau đây để trả về Stringtừ hoạt động làm tròn của mình:

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. Sử dụngNumberFormatter

Nếu bạn muốn nhận được String?từ hoạt động làm tròn của mình, hãy NumberFormattercung cấp một giải pháp tùy biến cao.

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")

1
Câu trả lời chính xác. Tôi có thể đề xuất trên # 5 rằng bạn có thể cân nhắc sử dụng Decimal, đây là cầu nối miễn phí NSDecimalNumber. Decimallà loại có nguồn gốc và cung cấp Swift hỗ trợ thanh lịch hơn cho các nhà khai thác bản địa như +, -vv
Rob

@Rob Tôi đã cập nhật câu trả lời của tôi với NSDecimalRound(_:_:_:_:)chức năng. Cảm ơn.
Imanou Petit

Sử dụng lựa chọn số 9 sẽ đảm bảo rằng bạn sẽ mong đợi phân số cố định (số chữ số chính xác), giả sử số thập phân 43.12345 và phân số = 6, bạn nhận được 43.123450
Almas Adilbek

1
@ImanouPetit Cảm ơn bạn đã đăng bài này. Tôi có thể nuke một vài phần mở rộng.
Adrian

Tôi buồn NumberFormatterlà lựa chọn cuối cùng trong khi nó phải là lựa chọn đầu tiên để trình bày số cho người dùng. Không có phương pháp khác tạo ra số địa phương đúng.
Sulthan

93

Trong Swift 2.0 và Xcode 7.2:

let pi: Double = 3.14159265358979
String(format:"%.2f", pi)

Thí dụ:

nhập mô tả hình ảnh ở đây


50

Đây là một mã làm việc đầy đủ

Swift 3.0 / 4.0 / 5.0, Xcode 9.0 GM / 9.2 trở lên

let doubleValue : Double = 123.32565254455
self.lblValue.text = String(format:"%.f", doubleValue)
print(self.lblValue.text)

đầu ra - 123

let doubleValue : Double = 123.32565254455
self.lblValue_1.text = String(format:"%.1f", doubleValue)
print(self.lblValue_1.text)

đầu ra - 123.3

let doubleValue : Double = 123.32565254455
self.lblValue_2.text = String(format:"%.2f", doubleValue)
print(self.lblValue_2.text)

đầu ra - 123,33

let doubleValue : Double = 123.32565254455
self.lblValue_3.text = String(format:"%.3f", doubleValue)
print(self.lblValue_3.text)

đầu ra - 123.326


1
một dòng?, có vẻ như 3 dòng;)
Petter Friberg

bạn không thể tính toán mọi thứ bằng chuỗi, tôi không nghĩ đó là câu trả lời đúng vì nó chỉ để hiển thị.
JBarros35

25

Dựa trên câu trả lời của Yogi, đây là chức năng Swift thực hiện công việc:

func roundToPlaces(value:Double, places:Int) -> Double {
    let divisor = pow(10.0, Double(places))
    return round(value * divisor) / divisor
}

20

Trong Swift 3.0 và Xcode 8.0:

extension Double {
    func roundTo(places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return (self * divisor).rounded() / divisor
    }
}

Sử dụng tiện ích mở rộng này như vậy:

let doubleValue = 3.567
let roundedValue = doubleValue.roundTo(places: 2)
print(roundedValue) // prints 3.56

19

Swift 4, Xcode 10

yourLabel.text =  String(format:"%.2f", yourDecimalValue)

1
Tôi đã không downvote, nhưng tôi nghĩ lý do có thể là vì điều này sẽ trả về một chuỗi đại diện của một số, không phải số. Sẽ tốt thôi nếu đó là tất cả những gì bạn cần nhưng bạn có thể muốn số đó được làm tròn để sử dụng tiếp. OP đã nói "khi tôi in" vì vậy tôi nghĩ rằng đây là một giải pháp chấp nhận được, dễ dàng và sạch sẽ trong trường hợp này.
Ben Stahl

1
Hoàn hảo. Giải pháp một dòng. Tôi chỉ cần hiển thị giá trị thập phân dưới dạng Chuỗi trong nhãn của mình.
zeeshan

18

Mã cho các chữ số cụ thể sau số thập phân là:

var a = 1.543240952039
var roundedString = String(format: "%.3f", a)

Ở đây,% .3f nói với swift để làm cho số này được làm tròn đến 3 chữ số thập phân. Và nếu bạn muốn số kép, bạn có thể sử dụng mã này:

// Chuỗi thành gấp đôi

var roundedString = Double(String(format: "%.3f", b))


14

Sử dụng thư viện Foundation Darwin được xây dựng

Chuyển 3

extension Double {
    func round(to places: Int) -> Double {
        let divisor = pow(10.0, Double(places))
        return Darwin.round(self * divisor) / divisor
    }
}

Sử dụng:

let number:Double = 12.987654321
print(number.round(to: 3)) 

Đầu ra: 12.988


9

Một cách tiện dụng có thể là sử dụng phần mở rộng của loại Double

extension Double {
    var roundTo2f: Double {return Double(round(100 *self)/100)  }
    var roundTo3f: Double {return Double(round(1000*self)/1000) }
}

Sử dụng:

let regularPie:  Double = 3.14159
var smallerPie:  Double = regularPie.roundTo3f  // results 3.142
var smallestPie: Double = regularPie.roundTo2f  // results 3.14

9

Nếu bạn muốn làm tròn Doublecác giá trị, bạn có thể muốn sử dụng Swift Decimalđể bạn không đưa ra bất kỳ lỗi nào có thể phát sinh khi cố gắng tính toán với các giá trị được làm tròn này. Nếu bạn sử dụng Decimal, nó có thể biểu thị chính xác các giá trị thập phân của giá trị dấu phẩy động tròn đó.

Vì vậy, bạn có thể làm:

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
    }
}

Sau đó, bạn có thể nhận được Decimalgiá trị làm tròn như vậy:

let foo = 427.3000000002
let value = foo.roundedDecimal(to: 2) // results in 427.30

Và nếu bạn muốn hiển thị nó với một số vị trí thập phân được chỉ định (cũng như bản địa hóa chuỗi cho ngôn ngữ hiện tại của người dùng), bạn có thể sử dụng NumberFormatter:

let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2

if let string = formatter.string(for: value) {
    print(string)
}

2
Câu trả lời tốt nhất cho đến nay.
Codetard

(4.81).roundedDecimal(to: 2, mode: .down)sẽ trả về 4,8 thay vì 4,81, sử dụng Decimal(string: self.description)!cho chính xácdecimalValue
vk.edward.li

1
@ vk.edward.li - Có, người ta nên cảnh giác về việc làm tròn số thập phân lên / xuống, bởi vì các giá trị như 4,81 đơn giản là không thể được biểu diễn chính xác bằng Double(nó trở thành 4.8099999999999996). Nhưng tôi khuyên bạn không nên sử dụng description(vì việc làm tròn mà nó sử dụng không được ghi lại và có thể thay đổi). Nếu bạn thực sự muốn làm toán chính xác thập phân, bạn nên tránhDouble hoàn toàn và thay vào đó nên sử dụng Decimaltrực tiếp (ví dụ Decimal(sign: .plus, exponent: -2, significand: 481)hoặc Decimal(string: "4.81"). Nhưng không sử dụng description.
Rob

@Rob thường không thể lấy giá trị chuỗi là "4,81" nếu nó được lưu trữ dưới dạng Double, vì vậy bạn phải sử dụng self.descrip (thuật toán Grisu2 đã sửa đổi) để sửa độ chính xác đã bị mất
vk.edward.li

Tôi hiểu quan điểm của bạn. Tôi chỉ không đồng ý với giải pháp của bạn. Hành vi làm tròn của descriptionphương pháp không được ghi lại cũng không được đảm bảo. Thêm vào đó, nó không được bản địa hóa. IMHO, đó là một sai lầm khi sử dụng descriptioncho bất kỳ mục đích nào khác ngoài mục đích đăng nhập. Tôi sẽ sử dụng Decimalxuyên suốt, tránh sử dụng Doublehoàn toàn hoặc chỉ sử dụng chế độ làm tròn khác. Hoặc, nếu bạn phải, sử dụng phương pháp bản địa hóa của riêng bạn sử dụng thuật toán kiểu Grisu (nhưng điều đó dường như không cần thiết khi bạn biết bạn muốn làm tròn bao nhiêu vị trí thập phân). Nhưng tôi sẽ tránh dựa vào hành vi phụ trợ này của description.
Cướp

8

Đây là một cách giải quyết lâu dài, có thể có ích nếu nhu cầu của bạn phức tạp hơn một chút. Bạn có thể sử dụng một định dạng số trong Swift.

let numberFormatter: NSNumberFormatter = {
    let nf = NSNumberFormatter()
    nf.numberStyle = .DecimalStyle
    nf.minimumFractionDigits = 0
    nf.maximumFractionDigits = 1
    return nf
}()

Giả sử biến bạn muốn in là

var printVar = 3.567

Điều này sẽ đảm bảo nó được trả về ở định dạng mong muốn:

numberFormatter.StringFromNumber(printVar)

Do đó, kết quả ở đây sẽ là "3.6" (làm tròn). Mặc dù đây không phải là giải pháp kinh tế nhất, tôi đưa ra vì OP đã đề cập đến việc in ấn (trong trường hợp đó là một Chuỗi không mong muốn) và vì lớp này cho phép đặt nhiều tham số.


1
Một lưu ý nhanh rằng bất kỳ trình định dạng nào đều khá tốn kém về mặt lập trình, khiến nó trở nên khó hiểu đối với các nhiệm vụ cần được thực hiện nhanh chóng hoặc lặp đi lặp lại.
Jonathan Thornton

7

tôi sẽ dùng

print(String(format: "%.3f", totalWorkTimeInHours))

và thay đổi .3f thành bất kỳ số thập phân nào bạn cần


Anh ấy muốn in với 3 chữ số, không được lấy trong NSTimeInterval
Mohsen Hossein đổ vào

7

Hoặc:

  1. Sử dụng String(format:):

    • Định kiểu Doubleđể String%.3fformat specifier và sau đó trở lạiDouble

      Double(String(format: "%.3f", 10.123546789))!
    • Hoặc mở rộng Doubleđể xử lý các vị trí N-Decimal:

      extension Double {
          func rounded(toDecimalPlaces n: Int) -> Double {
              return Double(String(format: "%.\(n)f", self))!
          }
      }
  2. Theo tính toán

    • nhân với 10 ^ 3, làm tròn nó và sau đó chia cho 10 ^ 3 ...

      (1000 * 10.123546789).rounded()/1000
    • Hoặc mở rộng Doubleđể xử lý các vị trí N-Decimal:

      extension Double {    
          func rounded(toDecimalPlaces n: Int) -> Double {
              let multiplier = pow(10, Double(n))
              return (multiplier * self).rounded()/multiplier
          }
      }

6

Đây là thuật toán linh hoạt hơn để làm tròn đến N chữ số có nghĩa

Giải pháp Swift 3

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

6

Cách tốt nhất để định dạng một thuộc tính kép là sử dụng các phương thức được xác định trước của Apple.

mutating func round(_ rule: FloatingPointRoundingRule)

FloatingPointRoundingRule là một enum có các khả năng sau

Các trường hợp liệt kê:

case AwayFromZero Làm tròn đến giá trị được phép gần nhất có cường độ lớn hơn hoặc bằng giá trị của nguồn.

trường hợp xuống Vòng đến giá trị cho phép gần nhất nhỏ hơn hoặc bằng nguồn.

trường hợp toNearestOrAwayFromZero Làm tròn đến giá trị được phép gần nhất; nếu hai giá trị gần bằng nhau, thì giá trị lớn hơn sẽ được chọn.

trường hợp toNearestOrEven Làm tròn đến giá trị được phép gần nhất; nếu hai giá trị gần bằng nhau, thì một giá trị chẵn được chọn.

trường hợp đối vớiZero Round đến giá trị được phép gần nhất có cường độ nhỏ hơn hoặc bằng giá trị của nguồn.

trường hợp Làm tròn đến giá trị được phép gần nhất lớn hơn hoặc bằng nguồn.

var aNumber : Double = 5.2
aNumber.rounded(.up) // 6.0

6

làm tròn một giá trị gấp đôi thành x số thập phân
NO. các chữ số sau số thập phân

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

Điều gì đang xảy ra với mã này? Ba ví dụ chứng minh điều gì?
rene

Mã chỉ câu trả lời là không hữu ích, xin vui lòng cố gắng giải thích những gì mỗi ví dụ này làm.
Moe

5

Không phải Swift nhưng tôi chắc chắn bạn sẽ hiểu.

pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;

4

Điều này dường như hoạt động trong Swift 5.

Khá ngạc nhiên khi không có chức năng tiêu chuẩn cho việc này.

// Cắt ngắn từ hai đến n vị trí thập phân với làm tròn

extension Double {

    func truncate(to places: Int) -> Double {
    return Double(Int((pow(10, Double(places)) * self).rounded())) / pow(10, Double(places))
    }

}

2

Bạn có thể thêm phần mở rộng này:

extension Double {
    var clean: String {
        return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)
    }
}

và gọi nó như thế này:

let ex: Double = 10.123546789
print(ex.clean) // 10.12

Đây là một triển khai gọn gàng đại diện cho nó như là một Chuỗi. Tôi tự hỏi nếu có thể hoặc hợp lý để viết một phần mở rộng số lượng chữ số sau thời gian vẫn duy trì nó là Double.
thinkswift

2

Để tránh sự không hoàn hảo của Float, hãy sử dụng 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
    }
}

Ví dụ.
1075,58 vòng thành 1075,57 khi sử dụng Float với tỷ lệ: 2 và .down
1075,58 vòng thành 1075,58 khi sử dụng Decimal với tỷ lệ: 2 và .down


1

Tôi thấy điều này tự hỏi nếu có thể sửa lỗi đầu vào của người dùng. Đó là nếu họ nhập ba số thập phân thay vì hai cho một số tiền. Nói 1.11 thay vì 1.11 bạn có thể sửa nó bằng cách làm tròn không? Câu trả lời cho nhiều lý do là không! Với tiền, bất cứ thứ gì, tức là 0,001 cuối cùng sẽ gây ra vấn đề trong sổ séc thực.

Đây là một chức năng để kiểm tra đầu vào của người dùng cho quá nhiều giá trị sau khoảng thời gian. Nhưng sẽ cho phép 1., 1.1 và 1.11.

Giả định rằng giá trị đã được kiểm tra để chuyển đổi thành công từ Chuỗi thành 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


}

1
//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"

1
extension String{
  var roundedValue:String {
     return String(format: "%.3f", self)
}}

Sử dụng :

totalWorkTimeInHours.roundedValue

1

Đây là một cho SwiftUI nếu bạn cần một phần tử Văn bản có giá trị số.

struct RoundedDigitText : View {
    let digits : Int
    let number : Double

    var body : some View {
        Text(String(format: "%.\(digits)f", number))
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.