Membulatkan nilai ganda ke x jumlah desimal di deras


395

Adakah yang bisa memberi tahu saya cara membulatkan nilai ganda ke x jumlah tempat desimal di Swift?

Saya sudah:

var totalWorkTimeInHours = (totalWorkTime/60/60)

Dengan totalWorkTimemenjadi NSTimeInterval (dobel) di detik.

totalWorkTimeInHours akan memberi saya jam, tapi itu memberi saya jumlah waktu dalam jumlah yang tepat panjang misalnya 1,543240952039 ......

Bagaimana saya membulatkan ini menjadi, katakanlah, 1,543 ketika saya mencetak totalWorkTimeInHours?


1
Lihat jawaban saya untuk menemukan hingga 9 cara yang berbeda untuk melengkapi ganda menggunakan Darwin round(_:), Double round(), NSStringinitializer, Stringinitializer, NumberFormatter, ekstensi ganda atau bahkan NSDecimalNumberdan Decimal.
Imanou Petit

@Rounded, pembungkus properti cepat 5.1: gist.github.com/abhijithpp/1cc41b41a5d1c8f007da90f20bc0c65f
Abhijith

Jawaban:


389

Anda dapat menggunakan roundfungsi Swift untuk mencapai ini.

Untuk membulatkan a Doubledengan presisi 3 digit, pertama kalikan dengan 1000, bulatkan dan bagi hasil bulat dengan 1000:

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

Selain segala jenis printf(...)atau String(format: ...)solusi, hasil operasi ini masih bertipe Double.

EDIT:
Mengenai komentar yang terkadang tidak berfungsi, baca ini:

Yang Harus Diketahui Setiap Programmer Tentang Aritmatika Floating-Point


Untuk beberapa alasan itu tidak membantu .. Saya menggunakan ini dalam kasus berikut TransformOf <Double, String> (fromJSON: {Double (round (($ 0! As NSString) .doubleValue * 100) / 100)}, toJSON: {"($ 0)"})
Fawkes

29
Tidak bekerja untuk saya di taman bermain: let rate = 9.94999999999; Double(round(rate * 100) / 100);Output: 9.94999999999, 9.949999999999999Hanya berfungsi untuk cetak tetapi bagaimana saya bisa menetapkannya ke variabel?
Alexander Yakovlev

Anda harus menggunakan Desimal untuk ini, bukan Doubles biasa.
csotiriou

13
"Apa Yang Harus Diketahui Setiap Ilmuwan Mengenai Aritmatika Titik Apung" adalah sepanjang 73 halaman. Apa TL; DR itu? :)
JaredH

1
@HardikDG Saya tidak ingat, maaf :-)
Alexander Yakovlev

431

Perpanjangan untuk Swift 2

Solusi yang lebih umum adalah ekstensi berikut, yang berfungsi dengan 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
    }
}


Perpanjangan untuk Swift 3

In Swift 3 rounddigantikan oleh 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
    }
}


Contoh yang mengembalikan Double dibulatkan ke 4 tempat desimal:

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
Sifat dari Swift's Double tampaknya tidak tepat - karena cara itu disimpan / diakses dalam biner, bahkan menggunakan fungsi pembulatan ini tidak akan mengembalikan angka yang dibulatkan ke 3 tempat desimal: misalnya, round(8.46 * pow(10.0, 3.0)) / pow(10.0, 3.0)kembali 8.460000000000001. Melakukan hal yang sama dengan Float, setidaknya dalam skenario ini , pada kenyataannya tampaknya berhasil: round(Float(8.46) * pow(10.0, 3.0)) / pow(10.0, 3.0)hasil 8.46. Hanya sesuatu yang perlu diperhatikan.
Ben Saufley

2
Sayangnya, ini tidak lagi berfungsi di Swift 3, saya mendapatkan kesalahan iniNo '*' candidates produce the expected contextual result type 'FloatingPointRoundingRule'
koen

2
Saya memperbarui solusi dan menambahkan ekstensi untuk Swift 3.
Sebastian

2
Agar lebih cepat 3 ... Anda harus berubah untuk func rounded (toPlaces places: Int) -> Double
FouZ

2
@BenSaufley Tapi itu juga tidak berfungsi jika Anda memasukkan 98.68. Dalam hal ini, saya mendapatkan 98.6800003
Alexander Khitev

340

Bagaimana saya membulatkan ini menjadi, katakanlah, 1,543 ketika saya mencetak totalWorkTimeInHours ?

Untuk membulatkan totalWorkTimeInHoursmenjadi 3 digit untuk dicetak, gunakan Stringkonstruktor yang mengambil formatstring:

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

24
Itu pemotongan, bukan pembulatan
Eyeball

33
@Eyeball: Sebenarnya, APAKAH DILAKUKAN. Ini adalah perilaku yang sama dengan fungsi C printf, yang membulatkan ke angka yang diminta. Jadi String(format: "%.3f", 1.23489)cetakan1.235
zisoft

6
Poster asli mencari nilai numerik untuk digunakan, bukan string untuk ditampilkan.
pr1001

17
@ pr1001, mungkin begitu, tetapi itu tidak jelas pada saat itu dan 46 lainnya telah menemukan jawaban saya berguna. Stack Overflow lebih dari sekedar membantu OP.
vacawama

3
aneh, ini mengembalikan 0,00 setiap kali.
Eric H

254

Dengan Swift 5, sesuai dengan kebutuhan Anda, Anda dapat memilih salah satu dari 9 gaya berikut untuk mendapatkan hasil yang bulat dari a Double.


# 1. Menggunakan FloatingPoint rounded()metode

Dalam kasus paling sederhana, Anda dapat menggunakan Double rounded()metode ini.

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. Menggunakan FloatingPoint rounded(_:)metode

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. Menggunakan roundfungsi Darwin

Foundation menawarkan roundfungsi melalui 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 Menggunakan Doublemetode kustom ekstensi yang dibangun dengan Darwin rounddan powfungsinya

Jika Anda ingin mengulangi operasi sebelumnya berkali-kali, refactoring kode Anda bisa menjadi ide yang bagus.

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 Menggunakan NSDecimalNumber rounding(accordingToBehavior:)metode

Jika perlu, NSDecimalNumbertawarkan solusi verbose tapi kuat untuk membulatkan angka desimal.

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. Menggunakan NSDecimalRound(_:_:_:_:)fungsi

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. Menggunakan NSString init(format:arguments:)inisialisasi

Jika Anda ingin mengembalikan a NSStringdari operasi pembulatan Anda, menggunakan NSStringinitializer adalah solusi yang sederhana namun efisien.

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. Menggunakan String init(format:_:)inisialisasi

StringTipe Swift dijembatani dengan NSStringkelas Foundation . Oleh karena itu, Anda dapat menggunakan kode berikut untuk mengembalikan a Stringdari operasi pembulatan Anda:

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. MenggunakanNumberFormatter

Jika Anda berharap untuk mendapatkan String?dari operasi pembulatan Anda, NumberFormattermenawarkan solusi yang sangat dapat disesuaikan.

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
Jawaban yang bagus Saya mungkin menyarankan pada # 5 yang mungkin Anda pertimbangkan untuk digunakan Decimal, yang bebas biaya tol NSDecimalNumber. Decimaladalah jenis asli Swift dan menawarkan dukungan lebih elegan untuk operator asli seperti +, -, dll
Rob

@Rob Saya sudah memperbarui jawaban saya dengan NSDecimalRound(_:_:_:_:)fungsi. Terima kasih.
Imanou Petit

Menggunakan pilihan # 9 akan menjamin bahwa Anda akan mengharapkan fraksi tetap (jumlah digit presisi), katakanlah angka desimal 43.12345 dan fraksi = 6, Anda mendapatkan 43.123450
Almas Adilbek

1
@ImanouPetit Terima kasih telah memposting ini. Saya bisa nuke beberapa ekstensi.
Adrian

Saya sedih NumberFormatteradalah pilihan terakhir sementara itu harus menjadi yang pertama untuk menyajikan angka kepada pengguna. Tidak ada metode lain yang menghasilkan angka yang dilokalkan dengan benar.
Sulthan

93

Di Swift 2.0 dan Xcode 7.2:

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

Contoh:

masukkan deskripsi gambar di sini


50

Ini adalah kode yang berfungsi penuh

Swift 3.0 / 4.0 / 5.0, Xcode 9.0 GM / 9.2 dan di atasnya

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)

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


1
satu baris ?, sepertinya 3 baris;)
Petter Friberg

Anda tidak dapat menghitung hal-hal menggunakan string, saya tidak berpikir itu jawaban yang benar karena hanya untuk ditampilkan.
JBarros35

25

Membangun jawaban Yogi, inilah fungsi Swift yang berfungsi:

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

20

Di Swift 3.0 dan Xcode 8.0:

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

Gunakan ekstensi ini seperti ini:

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
Saya tidak downvote, tapi saya pikir alasannya mungkin karena ini mengembalikan representasi string dari angka, bukan angka. Tidak apa-apa jika itu yang Anda butuhkan tetapi Anda mungkin ingin nomor itu sendiri dibulatkan untuk digunakan lebih lanjut. OP memang mengatakan "ketika saya mencetak" jadi saya pikir ini adalah solusi yang dapat diterima, mudah, dan bersih dalam kasus ini.
Ben Stahl

1
Sempurna. Solusi satu baris. Saya hanya perlu menunjukkan nilai desimal sebagai String di label saya.
zeeshan

18

Kode untuk digit tertentu setelah desimal adalah:

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

Di sini% .3f memberi tahu swift untuk membuat angka ini dibulatkan menjadi 3 tempat desimal. Dan jika Anda menginginkan angka ganda, Anda dapat menggunakan kode ini:

// String to Double

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


14

Gunakan perpustakaan Yayasan Darwin yang dibangun

SWIFT 3

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

Pemakaian:

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

Output: 12.988


9

Cara praktis bisa dengan menggunakan ekstensi tipe Double

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

Pemakaian:

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

9

Jika Anda ingin membulatkan Doublenilai, Anda mungkin ingin menggunakan Swift Decimalsehingga Anda tidak memperkenalkan kesalahan yang dapat muncul saat mencoba menghitung dengan nilai-nilai ini. Jika Anda menggunakan Decimal, itu dapat secara akurat mewakili nilai desimal dari nilai titik mengambang bulat itu.

Jadi kamu bisa melakukan:

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

Kemudian, Anda bisa mendapatkan nilai bulat Decimalseperti:

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

Dan jika Anda ingin menampilkannya dengan jumlah tempat desimal tertentu (serta melokalisasi string untuk lokal pengguna saat ini), Anda dapat menggunakan NumberFormatter:

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

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

2
Jawaban terbaik sejauh ini.
Codetard

(4.81).roundedDecimal(to: 2, mode: .down)akan mengembalikan 4,8 bukannya 4,81, gunakan Decimal(string: self.description)!untuk tepatdecimalValue
vk.edward.li

1
@ vk.edward.li - Ya, kita harus waspada tentang pembulatan desimal ke atas / bawah, karena nilai-nilai seperti 4,81 tidak dapat diwakili secara akurat dengan Double(itu menjadi 4.8099999999999996). Tapi saya akan menyarankan agar tidak menggunakan description(karena pembulatannya tidak didokumentasikan dan dapat berubah). Jika Anda benar-benar ingin melakukan matematika desimal-akurat, Anda harus menghindari Doublesepenuhnya dan harus menggunakan Decimallangsung (misalnya Decimal(sign: .plus, exponent: -2, significand: 481)atau Decimal(string: "4.81"). Tapi jangan gunakan description.
Rob

@Rob biasanya tidak mungkin untuk mendapatkan nilai string "4.81" jika disimpan sebagai Double, jadi Anda harus menggunakan self.description (algoritma Grisu2 yang dimodifikasi) untuk memperbaiki presisi yang sudah hilang
vk.edward.li

Saya mengerti maksud Anda. Saya hanya tidak setuju dengan solusi Anda. Perilaku pembulatan descriptionmetode tidak didokumentasikan atau dijamin. Plus, itu tidak dilokalkan. IMHO, ini adalah kesalahan untuk digunakan descriptionselain untuk tujuan logging. Saya akan menggunakan Decimalseluruh, menghindari menggunakan Doublesepenuhnya, atau hanya menggunakan mode pembulatan berbeda. Atau, jika Anda harus, gunakan metode lokal Anda sendiri yang menggunakan algoritma gaya Grisu (tapi itu tampaknya tidak perlu ketika Anda tahu berapa banyak tempat desimal yang ingin Anda bulatkan). Tapi saya akan menghindari mengandalkan perilaku tambahan ini description.
Rob

8

Ini adalah semacam solusi yang panjang, yang mungkin berguna jika kebutuhan Anda sedikit lebih kompleks. Anda dapat menggunakan pemformat angka di Swift.

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

Misalkan variabel yang ingin Anda cetak adalah

var printVar = 3.567

Ini akan memastikan dikembalikan dalam format yang diinginkan:

numberFormatter.StringFromNumber(printVar)

Hasilnya di sini akan menjadi "3,6" (bulat). Meskipun ini bukan solusi yang paling ekonomis, saya memberikannya karena OP menyebutkan pencetakan (dalam hal ini String tidak tidak diinginkan), dan karena kelas ini memungkinkan untuk beberapa parameter ditetapkan.


1
Sebuah catatan cepat bahwa formatter apapun agak mahal secara program, membuatnya tidak disarankan untuk tugas-tugas yang perlu dilakukan dengan cepat atau berulang-ulang.
Jonathan Thornton

7

Saya akan menggunakan

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

dan ubah .3f ke sejumlah angka desimal yang Anda butuhkan


Dia ingin mencetak dengan 3 digit, bukan untuk mendapatkannya dalam NSTimeInterval
Mohsen Hossein tuangkan

7

Antara:

  1. Menggunakan String(format:):

    • Tipecast Doubleke Stringdengan penentu %.3fformat dan kemudian kembali keDouble

      Double(String(format: "%.3f", 10.123546789))!
    • Atau memperluas Doubleuntuk menangani tempat N-Desimal:

      extension Double {
          func rounded(toDecimalPlaces n: Int) -> Double {
              return Double(String(format: "%.\(n)f", self))!
          }
      }
  2. Dengan perhitungan

    • kalikan dengan 10 ^ 3, bulatkan dan kemudian bagi dengan 10 ^ 3 ...

      (1000 * 10.123546789).rounded()/1000
    • Atau memperluas Doubleuntuk menangani tempat N-Desimal:

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

6

Ini adalah algoritme pembulatan menjadi N yang lebih fleksibel

Solusi 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

Cara terbaik untuk memformat properti ganda adalah dengan menggunakan metode yang telah ditentukan Apple.

mutating func round(_ rule: FloatingPointRoundingRule)

FloatingPointRoundingRule adalah enum yang memiliki kemungkinan berikut

Kasus Pencacahan:

case awayFromZero Round ke nilai yang diizinkan terdekat yang besarnya lebih besar atau sama dengan yang dari sumber.

case down Round ke nilai yang diizinkan terdekat yang kurang dari atau sama dengan sumber.

case toNearestOrAwayFromZero Round dengan nilai yang diizinkan terdekat; jika dua nilai sama-sama dekat, yang dipilih dengan magnitudo lebih besar.

case toNearestOrEven Round ke nilai terdekat yang diizinkan; jika dua nilai sama dekat, yang genap dipilih.

case terhadap Zero Round ke nilai yang diizinkan terdekat yang besarnya kurang dari atau sama dengan yang dari sumber.

case up Round ke nilai yang diizinkan terdekat yang lebih besar dari atau sama dengan sumber.

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

6

bulatkan nilai ganda menjadi x angka desimal
NO. digit setelah desimal

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

Apa yang terjadi pada kode ini? Apa yang ditunjukkan ketiga contoh itu?
rene

Hanya jawaban kode yang tidak membantu, coba jelaskan apa yang masing-masing contoh ini lakukan.
Moe

5

Tidak Swift tapi saya yakin Anda mendapatkan idenya.

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

4

Ini sepertinya bekerja di Swift 5.

Cukup terkejut tidak ada fungsi standar untuk ini.

// Pemotongan dari tempat Double ke n-desimal dengan pembulatan

extension Double {

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

}

2

Anda dapat menambahkan ekstensi ini:

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

dan menyebutnya seperti ini:

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

Yang satu ini adalah implementasi yang rapi untuk merepresentasikannya sebagai sebuah String. Saya ingin tahu apakah mungkin atau rasional untuk menulis perpanjangan jumlah digit representasi setelah periode masih mempertahankannya sebagai Double.
thinkswift

2

Untuk menghindari cacat Float gunakan Desimal

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 putaran hingga 1075.57 saat menggunakan Float dengan skala: 2 dan. Turun
1075.58 putaran ke 1075.58 saat menggunakan Desimal dengan skala: 2 dan .down


1

Saya menemukan ini bertanya-tanya apakah mungkin untuk memperbaiki input pengguna. Itu jika mereka memasukkan tiga desimal bukan dua untuk jumlah dolar. Katakanlah 1.111 bukannya 1.11 bisakah Anda memperbaikinya dengan membulatkan? Jawabannya karena berbagai alasan adalah tidak! Dengan uang lebih dari 0,001 akhirnya akan menyebabkan masalah dalam buku cek nyata.

Berikut adalah fungsi untuk memeriksa input pengguna untuk terlalu banyak nilai setelah periode. Tetapi yang akan memungkinkan 1., 1.1 dan 1.11.

Diasumsikan bahwa nilai telah diperiksa untuk konversi yang berhasil dari String ke 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)
}}

Penggunaan:

totalWorkTimeInHours.roundedValue

1

Ini satu untuk SwiftUI jika Anda membutuhkan elemen Teks dengan nilai angka.

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

    var body : some View {
        Text(String(format: "%.\(digits)f", number))
    }
}
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.