web-dev-qa-db-ja.com

Doubleで最も近いIntに素早く丸める方法は?

私は結果を最も近い整数に丸めてそこから再計算するような成長率の計算機(Double)を作成しようとしています。

let firstUsers = 10.0
let growth = 0.1
var users = firstUsers
var week = 0


while users < 14 {
    println("week \(week) has \(users) users")
    users += users * growth
    week += 1
}

しかし、私はこれまで不可能でした。

EDITちょっとこんな感じでした:

var firstUsers = 10.0
let growth = 0.1
var users:Int = Int(firstUsers)
var week = 0


while users <= 14 {
    println("week \(week) has \(users) users")
    firstUsers += firstUsers * growth
    users = Int(firstUsers)
    week += 1
}

それが常に切り捨てることを気にしないが、firstUsersが変数になってプログラム全体で(次の計算を行うために)変更されなければならなかったので、それは好きではありません。 。

139
duarte harris

roundライブラリにはFoundationがあります(実際にはDarwinに含まれていますが、FoundationDarwinをインポートしています。 Foundationを直接使用するのではなく、Darwinを使用する

import Foundation

users = round(users)

遊び場でコードを実行してから呼び出す:

print(round(users))

出力:

15.0

round()は、小数点以下の桁数が>= .5の場合は常に切り上げ、< .5の場合は切り捨てます(標準丸め)。強制的に切り捨てる場合はfloor()を、強制的に切り上げる場合はceil()を使用できます。

特定の場所に丸める必要がある場合は、pow(10.0, number of places)を掛けてroundを付け、次にpow(10, number of places)で割ります。

小数点以下2桁に丸めます。

let numberOfPlaces = 2.0
let multiplier = pow(10.0, numberOfPlaces)
let num = 10.12345
let rounded = round(num * multiplier) / multiplier
print(rounded)

出力:

10.12

注:浮動小数点演算が機能する方法により、roundedは必ずしも完全に正確とは限りません。丸めの近似と考えてみるのが最善です。表示目的でこれを行っている場合は、数値を丸めるために数学を使用するのではなく、文字列フォーマットを使用して数値をフォーマットすることをお勧めします。

209
Mike S

Doubleを最も近い整数に丸めるには、 round() を使うだけです。

var x = 3.7
x.round() // x = 4.0

元の値を変更したくない場合は、 rounded() を使用してください。

let x = 3.7
let y = x.rounded() // y = 4.0. x = 3.7

予想されるように( またはそうではない )、3.5のような数字は切り上げられ、-3.5のような数字は切り捨てられます。それ以外の丸め動作が必要な場合は、 丸め規則 のいずれかを使用できます。例えば:

var x = 3.7
x.round(.towardZero) // 3.0

実際のIntname__が必要な場合は、それを1にキャストするだけです(ただし、DoubleがInt.maxより大きくならないことが確実な場合のみ)。

let myInt = Int(myDouble.rounded())

ノート

  • この答えは完全に書き直されています。私の以前の回答では、roundname__、lroundname__、floorname__、およびceilname__のようなC数学関数を扱いました。しかし、Swiftにこの機能が組み込まれているので、これらの機能を使用することはお勧めできません。これを指摘してくれた@dfriに感謝します。チェックアウト @ dfriの優れた答えはここCGFloatname __の丸め についても同様のことをしました。
123
Suragch

Swift 3&4-FloatingPointプロトコルでブループリントされたrounded(_:)メソッドを利用する

FloatingPoint protocol (例:DoubleおよびFloatが準拠する)ブループリントは rounded(_:)メソッド

func rounded(_ rule: FloatingPointRoundingRule) -> Self

ここで、 FloatingPointRoundingRule は、さまざまな丸め規則を列挙した列挙型です。

case awayFromZero

マグニチュードがソースのマグニチュード以上である最も近い許容値に丸めます。

case down

ソース以下の最も近い許容値に丸めます。

case toNearestOrAwayFromZero

最も近い許容値に丸めます。 2つの値が等しく近い場合、大きさが大きい方が選択されます。

case toNearestOrEven

最も近い許容値に丸めます。 2つの値が等しく近い場合、偶数の値が選択されます。

case towardZero

マグニチュードがソースのマグニチュード以下である最も近い許容値に丸めます。

case up

ソース以上の最も近い許容値に丸めます。

@ Suragch's excellent answer の例と同様の例を使用して、これらの異なる丸めオプションを実際に示します。

.awayFromZero

マグニチュードがソースのマグニチュード以上である最も近い許容値に丸めます。これは、selfの正の値と負の値に対して、それぞれceilfloor、またはselfの符号を条件として使用するため、C関数間で直接相当するものはありません。

3.000.rounded(.awayFromZero) // 3.0
3.001.rounded(.awayFromZero) // 4.0
3.999.rounded(.awayFromZero) // 4.0

(-3.000).rounded(.awayFromZero) // -3.0
(-3.001).rounded(.awayFromZero) // -4.0
(-3.999).rounded(.awayFromZero) // -4.0

.down

Cのfloor関数と同等です。

3.000.rounded(.down) // 3.0
3.001.rounded(.down) // 3.0
3.999.rounded(.down) // 3.0

(-3.000).rounded(.down) // -3.0
(-3.001).rounded(.down) // -4.0
(-3.999).rounded(.down) // -4.0

.toNearestOrAwayFromZero

Cのround関数と同等です。

3.000.rounded(.toNearestOrAwayFromZero) // 3.0
3.001.rounded(.toNearestOrAwayFromZero) // 3.0
3.499.rounded(.toNearestOrAwayFromZero) // 3.0
3.500.rounded(.toNearestOrAwayFromZero) // 4.0
3.999.rounded(.toNearestOrAwayFromZero) // 4.0

(-3.000).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.001).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.499).rounded(.toNearestOrAwayFromZero) // -3.0
(-3.500).rounded(.toNearestOrAwayFromZero) // -4.0
(-3.999).rounded(.toNearestOrAwayFromZero) // -4.0

この丸め規則は、引数ゼロ rounded() method を使用してアクセスすることもできます。

3.000.rounded() // 3.0
// ...

(-3.000).rounded() // -3.0
// ...

.toNearestOrEven

最も近い許容値に丸めます。 2つの値が同等に近い場合、偶数の値が選択されます。 Cのrint(/ nearbyintと非常に似ています)関数と同等です。

3.499.rounded(.toNearestOrEven) // 3.0
3.500.rounded(.toNearestOrEven) // 4.0 (up to even)
3.501.rounded(.toNearestOrEven) // 4.0

4.499.rounded(.toNearestOrEven) // 4.0
4.500.rounded(.toNearestOrEven) // 4.0 (down to even)
4.501.rounded(.toNearestOrEven) // 4.0

.towardZero

Cのtrunc関数と同等です。

3.000.rounded(.towardZero) // 3.0
3.001.rounded(.towardZero) // 3.0
3.999.rounded(.towardZero) // 3.0

(-3.000).rounded(.towardZero) // 3.0
(-3.001).rounded(.towardZero) // 3.0
(-3.999).rounded(.towardZero) // 3.0

丸めの目的が整数での動作を準備することである場合(たとえば、丸め後のIntの初期化によるFloatPointの使用)、単純にInt(またはDoubleなど)を使用してFloatを初期化するとき、切り捨てられます。

Int(3.000) // 3
Int(3.001) // 3
Int(3.999) // 3

Int(-3.000) // -3
Int(-3.001) // -3
Int(-3.999) // -3

.up

Cのceil関数と同等です。

3.000.rounded(.up) // 3.0
3.001.rounded(.up) // 4.0
3.999.rounded(.up) // 4.0

(-3.000).rounded(.up) // 3.0
(-3.001).rounded(.up) // 3.0
(-3.999).rounded(.up) // 3.0

補遺:FloatingPointのソースコードにアクセスして、さまざまなFloatingPointRoundingRuleルールとC関数が同等であることを確認します

必要に応じて、FloatingPointプロトコルのソースコードを見て、パブリックFloatingPointRoundingRuleルールに相当するC関数を直接確認できます。

Swift/stdlib/public/core/FloatingPoint.Swift.gyb から、rounded(_:)メソッドのデフォルトの実装により、変化するround(_:)メソッドが作成されることがわかります。

public func rounded(_ rule: FloatingPointRoundingRule) -> Self {
    var lhs = self
    lhs.round(rule)
    return lhs
}

Swift/stdlib/public/core/FloatingPointTypes.Swift.gyb から、round(_:)のデフォルト実装が見つかります。この実装では、FloatingPointRoundingRuleルールとC丸め関数の等価性が明らかです。

public mutating func round(_ rule: FloatingPointRoundingRule) {
    switch rule {
    case .toNearestOrAwayFromZero:
        _value = Builtin.int_round_FPIEEE${bits}(_value)
    case .toNearestOrEven:
        _value = Builtin.int_rint_FPIEEE${bits}(_value)
    case .towardZero:
        _value = Builtin.int_trunc_FPIEEE${bits}(_value)
    case .awayFromZero:
        if sign == .minus {
            _value = Builtin.int_floor_FPIEEE${bits}(_value)
        }
        else {
            _value = Builtin.int_ceil_FPIEEE${bits}(_value)
        }
    case .up:
        _value = Builtin.int_ceil_FPIEEE${bits}(_value)
    case .down:
        _value = Builtin.int_floor_FPIEEE${bits}(_value)
    }
}
66
dfri

Swift 3:特定の桁数に丸めたい場合は、 5.678434 - > 5.68 round()またはroundf()関数と乗算を組み合わせることができます。

    let value:Float = 5.678434
    let roundedValue = roundf(value * 100) / 100
    print(roundedValue) //5.68
5
Thoms
**In Swift**

var a = 14.123456789
var b = 14.123456789
var c = 14.123456789
var d = 14.123456789
var e = 14.123456789
var f = 14.123456789

a.rounded(.up)                      //15
b.rounded(.down)                    //14
c.rounded(.awayFromZero)            //15
d.rounded(.towardZero)              //14
e.rounded(.toNearestOrAwayFromZero) //14
f.rounded(.toNearestOrEven)         //14
2
Sai kumar Reddy

以下のようにSwift 3でFloatingPointを拡張することもできます。

extension FloatingPoint {
    func rounded(to n: Int) -> Self {
        return (self / Self(n)).rounded() * Self(n)

    }
}

324.0.rounded(to: 5)   // 325
1
Leo Dabus

スイフト3

var myNum = 8.09

myNum.rounded()// result = 8、myNumに格納されています。

1