Swiftで倍精度値を小数点以下の桁数に丸める方法を教えてもらえますか。
私は持っています:
var totalWorkTimeInHours = (totalWorkTime/60/60)
totalWorkTime
は秒のNSTimeInterval(double)です。
totalWorkTimeInHours
は私に時間を与えますが、それは私にそのような長い正確な数で時間量を与えます1.543240952039 ......
totalWorkTimeInHours
を印刷するとき、これをどのようにして例えば1.543に切り捨てますか?
これを実現するためにSwiftのround
関数を使うことができます。
Double
を3桁の精度で丸めるには、まずそれを1000倍してから丸め、その丸めた結果を1000で割る
let x = 1.23556789
let y = Double(round(1000*x)/1000)
print(y) // 1.236
どんな種類のprintf(...)
またはString(format: ...)
解決策を除いて、この操作の結果はまだDouble
型です。
編集:
それが時々うまくいかないというコメントに関しては、これを読んでください:
より一般的な解決策は、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
}
}
Swift 3では、round
は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
}
}
Doubleを小数点以下4桁に丸めた例
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
これを切り捨てて、たとえば1.543 と表示すると
totalWorkTimeInHours
となりますか。
印刷のためにtotalWorkTimeInHours
を3桁に丸めるには、String
文字列をとるformat
コンストラクタを使用します。
print(String(format: "%.3f", totalWorkTimeInHours))
Swift 4.2では、あなたの必要性に応じて、Double
name__から丸められた結果を得るために、 9以下のスタイル のいずれかを選ぶことができます。
FloatingPoint
rounded()
methodの使用最も単純なケースでは、Double
round()
メソッドを使うことができます。
let roundedValue1 = (0.6844 * 1000).rounded() / 1000
let roundedValue2 = (0.6849 * 1000).rounded() / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
FloatingPoint
rounded(_:)
methodの使用var roundedValue1 = (0.6844 * 1000).rounded(.toNearestOrEven) / 1000
var roundedValue2 = (0.6849 * 1000).rounded(.toNearestOrEven) / 1000
print(roundedValue1) // returns 0.684
print(roundedValue2) // returns 0.685
round
name__関数を使用するFoundationはDarwin経由でround
name__関数を提供しています。
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
Double
name__およびround
name__関数で構築されたpow
name__拡張カスタムメソッドの使用前の操作を何度も繰り返したい場合は、コードをリファクタリングすることをお勧めします。
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
NSDecimalNumber
rounding(accordingToBehavior:)
methodの使用必要に応じて、NSDecimalNumber
name__は10進数を丸めるための冗長で強力な解決策を提供します。
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
NSDecimalRound(_:_:_:_:)
functionを使用する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
NSString
init(format:arguments:)
initializerの使用丸め演算からNSString
name__を返す場合は、NSString
name__イニシャライザを使用するのが簡単ですが効率的な解決策です。
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
String
init(format:_:)
initializerの使用SwiftのString
name__型は、FoundationのNSString
name__クラスとブリッジされています。したがって、丸め演算からString
name__を返すために次のコードを使用できます。
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
NumberFormatter
name__ を使用する丸め演算からString?
を取得する予定の場合は、NumberFormatter
name__を使用して高度にカスタマイズ可能なソリューションを提供します。
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")
Yogiの答えに基づいて、これが仕事をするSwift関数です。
func roundToPlaces(value:Double, places:Int) -> Double {
let divisor = pow(10.0, Double(places))
return round(value * divisor) / divisor
}
これは完全に機能したコードです
Swift 3.0/4.0、Xcode 9.0 GM/9.2
let doubleValue : Double = 123.32565254455
self.lblValue.text = String(format:"%.f", doubleValue)
print(self.lblValue.text)
出力 - 123
self.lblValue_1.text = String(format:"%.1f", doubleValue)
print(self.lblValue_1.text)
出力 - 123.3
self.lblValue_2.text = String(format:"%.2f", doubleValue)
print(self.lblValue_2.text)
出力 - 123.33
self.lblValue_3.text = String(format:"%.3f", doubleValue)
print(self.lblValue_3.text)
出力 - 123.326
小数点以下の特定の桁のコードは次のとおりです。
var a = 1.543240952039
var roundedString = String(format: "%.3f", a)
ここで%.3fはSwiftにこの数字を小数点以下3桁に丸めるように指示します。二重の数字が必要な場合は、次のコードを使用できます。
// Doubleへの文字列
var roundedString = Double(String(format: "%.3f", b))
Swift 3.0およびXcode 8.0の場合:
extension Double {
func roundTo(places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return (self * divisor).rounded() / divisor
}
}
このようにこの拡張子を使う
let doubleValue = 3.567
let roundedValue = doubleValue.roundTo(places: 2)
print(roundedValue) // prints 3.56
Swift 4、Xcode 10
yourLabel.text = String(format:"%.2f", yourDecimalValue)
便利な方法は 拡張子 タイプ ダブル の使用です。
extension Double {
var roundTo2f: Double {return Double(round(100 *self)/100) }
var roundTo3f: Double {return Double(round(1000*self)/1000) }
}
使用法:
let regularPie: Double = 3.14159
var smallerPie: Double = regularPie.roundTo3f // results 3.142
var smallestPie: Double = regularPie.roundTo2f // results 3.14
組み込みのFoundation Darwinライブラリを使用します
スイフト3
extension Double {
func round(to places: Int) -> Double {
let divisor = pow(10.0, Double(places))
return Darwin.round(self * divisor) / divisor
}
}
使用法:
let number:Double = 12.987654321
print(number.round(to: 3))
出力:12.988
これは一種の長い回避策で、ニーズがもう少し複雑な場合に便利です。 Swiftでは数値フォーマッタを使うことができます。
let numberFormatter: NSNumberFormatter = {
let nf = NSNumberFormatter()
nf.numberStyle = .DecimalStyle
nf.minimumFractionDigits = 0
nf.maximumFractionDigits = 1
return nf
}()
印刷したい変数が
var printVar = 3.567
これにより、確実に目的の形式で返されるようになります。
numberFormatter.StringFromNumber(printVar)
したがって、ここでの結果は "3.6"(四捨五入)になります。これは最も経済的な解決策ではありませんが、OPが印刷(この場合はStringは望ましくない)について言及しているので、このクラスでは複数のパラメータを設定できるため、このようにします。
私は使うだろう
print(String(format: "%.3f", totalWorkTimeInHours))
そして.3fを必要な数の10進数に変更します
どちらか
String(format:)
を使う:
Double
を%.3f
フォーマット指定子でString
に型キャストしてからDouble
に戻す
Double(String(format: "%.3f", 10.123546789))!
あるいは、N-Decimalの場所を処理するようにDouble
を拡張します。
extension Double {
func rounded(toDecimalPlaces n: Int) -> Double {
return Double(String(format: "%.\(n)f", self))!
}
}
計算による
10 ^ 3で乗算し、それを丸めてから10 ^ 3で割ります...
(1000 * 10.123546789).rounded()/1000
あるいは、N-Decimalの場所を処理するようにDouble
を拡張します。
extension Double {
func rounded(toDecimalPlaces n: Int) -> Double {
let multiplier = pow(10, Double(n))
return (multiplier * self).rounded()/multiplier
}
}
これはN個の有効数字に丸めるより柔軟なアルゴリズムです。
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
Double
の値を四捨五入したい場合は、SwiftのDecimal
を使用することをお勧めします。そうすれば、四捨五入した値で計算しようとしたときに発生する可能性のあるエラーは発生しません。 Decimal
を使用すると、丸められた浮動小数点値の10進値を正確に表すことができます。
だからあなたはできる:
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
}
}
そうすると、丸められたDecimal
の値が次のようになります。
let foo = 427.3000000002
let value = foo.roundedDecimal(to: 2) // results in 427.30
また、指定された小数点以下の桁数で表示する場合(およびユーザーの現在のロケールに合わせて文字列をローカライズする場合)、NumberFormatter
を使用できます。
let formatter = NumberFormatter()
formatter.maximumFractionDigits = 2
formatter.minimumFractionDigits = 2
if let string = formatter.string(for: value) {
print(string)
}
迅速ではありませんが、私はあなたがアイデアを得ると確信しています。
pow10np = pow(10,num_places);
val = round(val*pow10np) / pow10np;
Doubleプロパティをフォーマットする最善の方法は、Appleの定義済みメソッドを使うことです。
mutating func round(_ rule: FloatingPointRoundingRule)
FloatingPointRoundingRuleは以下の可能性を持つ列挙型です。
列挙ケース:
case awayFromZero 大きさがソースの大きさ以上の最も近い許容値に丸めます。
case down 元の値以下の最も近い許容値に丸めます。
case toNearestOrAwayFromZero 最も近い許容値に丸めます。 2つの値が等しく近い場合は、大きさが大きい方が選択されます。
case toNearestOrEven 最も近い許容値に丸めます。 2つの値が等しく近い場合は、偶数の値が選択されます。
case aheadZero 大きさがソースの大きさ以下の最も近い許容値に丸めます。
case up source以上の最も近い許容値に丸めます。
var aNumber : Double = 5.2
aNumber.rounded(.up) // 6.0
double値をxの10進数に丸めます
いいえ。小数点以下の桁数
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
//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"
ユーザーの入力を修正することが可能かどうか、私はこれを疑問に思いました。それは彼らが2ドルではなく3ドルを入力した場合です。 1.11の代わりに1.111と言うと、丸めて修正できますか?多くの理由で答えはノーです!お金では、0.001を超えるものは、最終的に実際の小切手帳で問題を引き起こします。
これは、ユーザーが入力した期間後に多すぎる値をチェックするための機能です。しかし、それは1、1.1と1.11を可能にします。
値がStringから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
}
extension String{
var roundedValue:String {
return String(format: "%.3f", self)
}}
使用法 :
totalWorkTimeInHours.roundedValue
これはSwift 5で機能するようです。
すでにこれに標準的な機能がないことに驚いています。
//丸めを使用したDoubleからn桁までの切り捨て
extension Double {
func truncate(to places: Int) -> Double {
return Double(Int((pow(10, Double(places)) * self).rounded())) / pow(10, Double(places))
}
}
この拡張子を追加することができます:
extension Double {
var clean: String {
return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)
}
}
そしてこれを次のように呼ぶ:
let ex: Double = 10.123546789
print(ex.clean) // 10.12