web-dev-qa-db-ja.com

Swiftでdouble値を小数点以下の桁数に丸める

Swiftで倍精度値を小数点以下の桁数に丸める方法を教えてもらえますか。

私は持っています:

var totalWorkTimeInHours = (totalWorkTime/60/60)

totalWorkTimeは秒のNSTimeInterval(double)です。

totalWorkTimeInHoursは私に時間を与えますが、それは私にそのような長い正確な数で時間量を与えます1.543240952039 ......

totalWorkTimeInHoursを印刷するとき、これをどのようにして例えば1.543に切り捨てますか?

320
Leighton

これを実現するために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型です。

編集:
それが時々うまくいかないというコメントに関しては、これを読んでください:

すべてのコンピュータ科学者が浮動小数点演算について知っておくべきこと

330
zisoft

Swift 2用の拡張

より一般的な解決策は、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用のエクステンション

Swift 3では、roundroundedに置き換えられています。

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
385
Sebastian

これを切り捨てて、たとえば1.543 と表示すると totalWorkTimeInHoursとなりますか。

印刷のためにtotalWorkTimeInHoursを3桁に丸めるには、String文字列をとるformatコンストラクタを使用します。

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

Swift 4.2では、あなたの必要性に応じて、Doublename__から丸められた結果を得るために、 9以下のスタイル のいずれかを選ぶことができます。


#1 FloatingPointrounded() methodの使用

最も単純なケースでは、Doubleround()メソッドを使うことができます。

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 FloatingPointrounded(_:) 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

#3。 Darwin roundname__関数を使用する

FoundationはDarwin経由でroundname__関数を提供しています。

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。 DarwinのDoublename__およびroundname__関数で構築されたpowname__拡張カスタムメソッドの使用

前の操作を何度も繰り返したい場合は、コードをリファクタリングすることをお勧めします。

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。 NSDecimalNumberrounding(accordingToBehavior:) methodの使用

必要に応じて、NSDecimalNumbername__は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

#6。 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

#7。 NSStringinit(format:arguments:) initializerの使用

丸め演算からNSStringname__を返す場合は、NSStringname__イニシャライザを使用するのが簡単ですが効率的な解決策です。

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 Stringinit(format:_:) initializerの使用

SwiftのStringname__型は、FoundationのNSStringname__クラスとブリッジされています。したがって、丸め演算からStringname__を返すために次のコードを使用できます。

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。 NumberFormattername__ を使用する

丸め演算からString?を取得する予定の場合は、NumberFormattername__を使用して高度にカスタマイズ可能なソリューションを提供します。

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")
181
Imanou Petit

Swift 2.0とXcode 7.2の場合:

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

例:

enter image description here

86

Yogiの答えに基づいて、これが仕事をするSwift関数です。

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

これは完全に機能したコードです

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

18
Krunal Patel

小数点以下の特定の桁のコードは次のとおりです。

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

ここで%.3fはSwiftにこの数字を小数点以下3桁に丸めるように指示します。二重の数字が必要な場合は、次のコードを使用できます。

// Doubleへの文字列

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

16
Ramazan Karami

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
15
jaiswal Rajan

Swift 4、Xcode 10

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

便利な方法は 拡張子 タイプ ダブル の使用です。

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
9
Marco Leong

組み込みの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

9

これは一種の長い回避策で、ニーズがもう少し複雑な場合に便利です。 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は望ましくない)について言及しているので、このクラスでは複数のパラメータを設定できるため、このようにします。

7
Inkidu616

私は使うだろう

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

そして.3fを必要な数の10進数に変更します

7

どちらか

  1. 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))!
          }
      }
      
  2. 計算による

    • 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
          }
      }
      
6
staticVoidMan

これは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)
}
6
Rob

迅速ではありませんが、私はあなたがアイデアを得ると確信しています。

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

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
5
Abuzar Manzoor

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
5
Ayman Badr
//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

ユーザーの入力を修正することが可能かどうか、私はこれを疑問に思いました。それは彼らが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


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

使用法 :

totalWorkTimeInHours.roundedValue
0
Bhargav Sejpal

これは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))
    }

}
0
Matiu Awaiti

この拡張子を追加することができます:

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