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 totalWorkTime
menjadi 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
?
ios
swift
double
nstimeinterval
Leighton
sumber
sumber
round(_:)
,Double
round()
,NSString
initializer,String
initializer,NumberFormatter
, ekstensi ganda atau bahkanNSDecimalNumber
danDecimal
.Jawaban:
Anda dapat menggunakan
round
fungsi Swift untuk mencapai ini.Untuk membulatkan a
Double
dengan presisi 3 digit, pertama kalikan dengan 1000, bulatkan dan bagi hasil bulat dengan 1000:Selain segala jenis
printf(...)
atauString(format: ...)
solusi, hasil operasi ini masih bertipeDouble
.EDIT:
Mengenai komentar yang terkadang tidak berfungsi, baca ini:
Yang Harus Diketahui Setiap Programmer Tentang Aritmatika Floating-Point
sumber
let rate = 9.94999999999; Double(round(rate * 100) / 100);
Output:9.94999999999, 9.949999999999999
Hanya berfungsi untuk cetak tetapi bagaimana saya bisa menetapkannya ke variabel?Perpanjangan untuk Swift 2
Solusi yang lebih umum adalah ekstensi berikut, yang berfungsi dengan Swift 2 & iOS 9:
Perpanjangan untuk Swift 3
In Swift 3
round
digantikan olehrounded
:Contoh yang mengembalikan Double dibulatkan ke 4 tempat desimal:
sumber
round(8.46 * pow(10.0, 3.0)) / pow(10.0, 3.0)
kembali8.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)
hasil8.46
. Hanya sesuatu yang perlu diperhatikan.No '*' candidates produce the expected contextual result type 'FloatingPointRoundingRule'
Untuk membulatkan
totalWorkTimeInHours
menjadi 3 digit untuk dicetak, gunakanString
konstruktor yang mengambilformat
string:sumber
String(format: "%.3f", 1.23489)
cetakan1.235
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()
metodeDalam kasus paling sederhana, Anda dapat menggunakan
Double
rounded()
metode ini.# 2. Menggunakan
FloatingPoint
rounded(_:)
metode# 3. Menggunakan
round
fungsi DarwinFoundation menawarkan
round
fungsi melalui Darwin.# 4 Menggunakan
Double
metode kustom ekstensi yang dibangun dengan Darwinround
danpow
fungsinyaJika Anda ingin mengulangi operasi sebelumnya berkali-kali, refactoring kode Anda bisa menjadi ide yang bagus.
# 5 Menggunakan
NSDecimalNumber
rounding(accordingToBehavior:)
metodeJika perlu,
NSDecimalNumber
tawarkan solusi verbose tapi kuat untuk membulatkan angka desimal.# 6. Menggunakan
NSDecimalRound(_:_:_:_:)
fungsi# 7. Menggunakan
NSString
init(format:arguments:)
inisialisasiJika Anda ingin mengembalikan a
NSString
dari operasi pembulatan Anda, menggunakanNSString
initializer adalah solusi yang sederhana namun efisien.# 8. Menggunakan
String
init(format:_:)
inisialisasiString
Tipe Swift dijembatani denganNSString
kelas Foundation . Oleh karena itu, Anda dapat menggunakan kode berikut untuk mengembalikan aString
dari operasi pembulatan Anda:# 9. Menggunakan
NumberFormatter
Jika Anda berharap untuk mendapatkan
String?
dari operasi pembulatan Anda,NumberFormatter
menawarkan solusi yang sangat dapat disesuaikan.sumber
Decimal
, yang bebas biaya tolNSDecimalNumber
.Decimal
adalah jenis asli Swift dan menawarkan dukungan lebih elegan untuk operator asli seperti+
,-
, dllNSDecimalRound(_:_:_:_:)
fungsi. Terima kasih.NumberFormatter
adalah pilihan terakhir sementara itu harus menjadi yang pertama untuk menyajikan angka kepada pengguna. Tidak ada metode lain yang menghasilkan angka yang dilokalkan dengan benar.Di Swift 2.0 dan Xcode 7.2:
Contoh:
sumber
Ini adalah kode yang berfungsi penuh
Swift 3.0 / 4.0 / 5.0, Xcode 9.0 GM / 9.2 dan di atasnya
output - 123
keluaran - 123.3
output - 123,33
output - 123.326
sumber
Membangun jawaban Yogi, inilah fungsi Swift yang berfungsi:
sumber
Di Swift 3.0 dan Xcode 8.0:
Gunakan ekstensi ini seperti ini:
sumber
Swift 4, Xcode 10
sumber
Kode untuk digit tertentu setelah desimal adalah:
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:
var roundedString = Double(String(format: "%.3f", b))
sumber
Gunakan perpustakaan Yayasan Darwin yang dibangun
SWIFT 3
Pemakaian:
Output: 12.988
sumber
Cara praktis bisa dengan menggunakan ekstensi tipe Double
Pemakaian:
sumber
Jika Anda ingin membulatkan
Double
nilai, Anda mungkin ingin menggunakan SwiftDecimal
sehingga Anda tidak memperkenalkan kesalahan yang dapat muncul saat mencoba menghitung dengan nilai-nilai ini. Jika Anda menggunakanDecimal
, itu dapat secara akurat mewakili nilai desimal dari nilai titik mengambang bulat itu.Jadi kamu bisa melakukan:
Kemudian, Anda bisa mendapatkan nilai bulat
Decimal
seperti:Dan jika Anda ingin menampilkannya dengan jumlah tempat desimal tertentu (serta melokalisasi string untuk lokal pengguna saat ini), Anda dapat menggunakan
NumberFormatter
:sumber
(4.81).roundedDecimal(to: 2, mode: .down)
akan mengembalikan 4,8 bukannya 4,81, gunakanDecimal(string: self.description)!
untuk tepatdecimalValue
Double
(itu menjadi4.8099999999999996
). Tapi saya akan menyarankan agar tidak menggunakandescription
(karena pembulatannya tidak didokumentasikan dan dapat berubah). Jika Anda benar-benar ingin melakukan matematika desimal-akurat, Anda harus menghindariDouble
sepenuhnya dan harus menggunakanDecimal
langsung (misalnyaDecimal(sign: .plus, exponent: -2, significand: 481)
atauDecimal(string: "4.81")
. Tapi jangan gunakandescription
.description
metode tidak didokumentasikan atau dijamin. Plus, itu tidak dilokalkan. IMHO, ini adalah kesalahan untuk digunakandescription
selain untuk tujuan logging. Saya akan menggunakanDecimal
seluruh, menghindari menggunakanDouble
sepenuhnya, 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 inidescription
.Ini adalah semacam solusi yang panjang, yang mungkin berguna jika kebutuhan Anda sedikit lebih kompleks. Anda dapat menggunakan pemformat angka di Swift.
Misalkan variabel yang ingin Anda cetak adalah
Ini akan memastikan dikembalikan dalam format yang diinginkan:
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.
sumber
Saya akan menggunakan
dan ubah .3f ke sejumlah angka desimal yang Anda butuhkan
sumber
Antara:
Menggunakan
String(format:)
:Tipecast
Double
keString
dengan penentu%.3f
format dan kemudian kembali keDouble
Atau memperluas
Double
untuk menangani tempat N-Desimal:Dengan perhitungan
kalikan dengan 10 ^ 3, bulatkan dan kemudian bagi dengan 10 ^ 3 ...
Atau memperluas
Double
untuk menangani tempat N-Desimal:sumber
Ini adalah algoritme pembulatan menjadi N yang lebih fleksibel
Solusi Swift 3
sumber
Cara terbaik untuk memformat properti ganda adalah dengan menggunakan metode yang telah ditentukan Apple.
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.
sumber
bulatkan nilai ganda menjadi x angka desimal
NO. digit setelah desimal
sumber
Tidak Swift tapi saya yakin Anda mendapatkan idenya.
sumber
Ini sepertinya bekerja di Swift 5.
Cukup terkejut tidak ada fungsi standar untuk ini.
// Pemotongan dari tempat Double ke n-desimal dengan pembulatan
sumber
Anda dapat menambahkan ekstensi ini:
dan menyebutnya seperti ini:
sumber
Untuk menghindari cacat Float gunakan Desimal
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
sumber
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.
sumber
sumber
Penggunaan:
sumber
Ini satu untuk SwiftUI jika Anda membutuhkan elemen Teks dengan nilai angka.
sumber