신속하게 가장 가까운 Int로 Double을 반올림하는 방법은 무엇입니까?


170

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
}

그러나 나는 지금까지 할 수 없었습니다.

편집 내가 좀 그렇게 했어 :

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변수가되어 프로그램 전체에서 (다음 계산을하기 위해) 변경 해야했기 때문에 마음에 들지 않습니다.

답변:


253

라이브러리 에는 round사용할 수 Foundation있습니다 (실제로 가져 Darwin오지만 Foundation가져 오기 Darwin와 직접 사용하는 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항상 정확한 것은 아닙니다. 반올림의 근사치에 대해 더 생각하는 것이 가장 좋습니다. 표시 목적으로이 작업을 수행하는 경우 수학을 사용하여 반올림하는 대신 문자열 형식을 사용하여 숫자의 서식을 지정하는 것이 좋습니다.


pow()불행히도 놀이터에서 사용할 수 없습니다
MrBr

1
@MrBr는 pow()당신이 필요하므로, 다윈 라이브러리에 정의 된 import Darwin(또는 첫 번째 import Foundation또는 import Cocoa또는 import UIKit내부 다윈을 가져 결국 모두).
Mike S

54
또한 lround()을 반환하는 것도 Int있습니다.
Martin R

1
" round()소수점 이하 자릿수가> = .5이면 반올림하고 <.5 (표준 반올림)이면 내림합니다." 그렇지 않은 경우를 제외하고. round(-16.5)-16이 아닌 -17을 반환합니다. 이것이 버그입니까?
Daniel T.

1
@DanielT. -버그가 아닙니다. 가장 큰 음수로 반올림합니다. +16.5에서 +17은 0에서 0.5 더 멀어지고 있습니다. 즉, -16.5에서 -17도 0에서 0.5 더 멀다는 것을 의미합니다. Ceil은 정반대입니다. +16.5 ~ +16은 0에 0.5에 가깝고 -16.5 ~ -16도 0에 0.5에 가깝습니다
adougies

139

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

실제가 필요한 경우 Int하나로 캐스팅하십시오 (그러나 Double이보다 크지 않다고 확신하는 경우에만 Int.max).

let myInt = Int(myDouble.rounded())

노트

  • 이 답변은 완전히 다시 작성되었습니다. 내 오랜 대답은 수학 함수가 좋아하는 C 처리 round, lround, floor,와 ceil. 그러나 이제 Swift에이 기능이 내장되어 있으므로 더 이상 해당 기능을 사용하지 않는 것이 좋습니다. 이것을 지적 해 주신 @dfri에게 감사합니다. @dfri의 훌륭한 답변을 여기서 확인 하십시오 . 나는 또한 반올림에 대해CGFloat 비슷한 것을 했다 .

Int (myDouble.rounded ()) <--- double이 Int에 맞지 않으면 실제로 예외가 발생할 수 있습니다.
Toad

@Toad, 확실합니까? 나는 문서 에서 그것을 보지 못했다 .
Suragch

이 정확한 문제로 프로덕션에서 충돌이 발생했습니다. 그러나 내가 틀렸고 충돌하지 않더라도 여전히 doubles> maxint
Toad

1
@Toad, 그렇습니다. 좋은 지적입니다. 감사합니다. 답변에 메모를 추가했습니다.
Suragch

84

Swift 3 & 4- 프로토콜에 rounded(_:)청사진 으로 표시된 방법 사용FloatingPoint

FloatingPoint프로토콜은 (이 예에 DoubleFloat따르는 것으로) 청사진 rounded(_:)방법

func rounded(_ rule: FloatingPointRoundingRule) -> Self

FloatingPointRoundingRule여러 가지 다른 반올림 규칙을 열거하는 열거 형은 어디에 있습니까?

case awayFromZero

크기가 소스보다 크거나 같은 가장 가까운 허용 값으로 반올림합니다.

case down

소스보다 작거나 같은 가장 가까운 허용 값으로 반올림합니다.

case toNearestOrAwayFromZero

가장 가까운 허용 값으로 반올림합니다. 두 값이 동일하게 가까운 경우 더 큰 크기의 값이 선택됩니다.

case toNearestOrEven

가장 가까운 허용 값으로 반올림합니다. 두 값이 똑같이 가까운 경우 짝수 값이 선택됩니다.

case towardZero

크기가 소스의 크기보다 작거나 같은 가장 가까운 허용 값으로 반올림합니다.

case up

소스보다 크거나 같은 가장 가까운 허용 값으로 반올림합니다.

우리는 @Suragch의 탁월한 답변 과 유사한 예제를 사용 하여 실제로 이러한 다른 반올림 옵션을 보여줍니다.

.awayFromZero

크기가 소스의 크기보다 크거나 같은 가장 가까운 허용 값으로 반올림합니다. 아무 조건의 기호,이 용도로는 C 기능 중 상당 직접 self, ceil또는 floor의 양 및 음의 값을, self각각.

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

이 반올림 규칙은 zero argument rounded()메소드를 사용하여 액세스 할 수도 있습니다 .

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

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

.toNearestOrEven

가장 가까운 허용 값으로 반올림합니다. 두 값이 동일하게 가까운 경우 짝수 값이 선택됩니다. 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) // 5.0 (up to nearest)

.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사용하여 초기화 할 때 소수 부분이 잘린다는 사실을 이용할 수 있습니다.DoubleFloat

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프로토콜 의 소스 코드를 살펴보고 C FloatingPointRoundingRule규칙 이 공개 규칙 과 동등한 지 직접 확인할 수 있습니다 .

에서 신속 / 다음 stdlib / 공공 / 코어 / FloatingPoint.swift.gyb는 우리의 기본 구현 볼 rounded(_:)방법은 돌연변이의 우리를 만드는 round(_:)방법

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

에서 신속 / 다음 stdlib / 공공 / 코어 / 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)
    }
}

@iosMentalist 프롬프트를 표시해 주셔서 감사합니다. 답변 제목을 업데이트했습니다.
dfri

I는 임의의 식을 원한다면 = 3 3.0 = 3.5 3.1 = 3.5 3.4 3.6 = 4, 3.9, 등 - 4
PJR

6
**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

6

스위프트 3 : 특정 숫자 (예 : 5.678434-> 5.68)로 반올림하려면 round () 또는 roundf () 함수를 곱셈과 결합하면됩니다.

let value:Float = 5.678434
let roundedValue = roundf(value * 100) / 100
print(roundedValue) //5.68

4

다음과 같이 Swift 3에서 FloatingPoint를 확장 할 수도 있습니다.

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

    }
}

324.0.rounded(to: 5)   // 325

이것을 설명해 주시겠습니까? 무슨 Self뜻입니까?
JZAU

@Jacky Self는 FloatingPoint 클래스를 참조하고 self는 해당 클래스의 인스턴스를 나타냅니다.
George Yacoub

@GeorgeYacoub Self는 확장되고있는 (샘플 사용이 Double이라는 점에서) FloatingPoint를 따르는 유형을 나타내지 만 클래스가 아닌 구조입니다.
Leo Dabus

2

스위프트 3

var myNum = 8.09
myNum.rounded() // result = 8 and leaves myNum unmodified

좋은. 나는 이것에 대해 전에 몰랐다. 한 참고 : myNum.rounded()변경되지 않습니다 myNum,하지만 myNum.round()않습니다.
Suragch

@Suragch, 귀하의 의견을 반영하여 답변을 편집했습니다.
Adil Hussain

0

값을 Int로 변환하기 전에 double이 max Int 값보다 높은지 확인할 수도 있습니다.

let number = Double.infinity
if number >= Double(integerLiteral: Int64.max) {
  let rounded = Int.max
} else {
  let rounded = Int(number.rounded())
}

-1

매우 쉬운 해결책이 나를 위해 일했습니다.

  if (62 % 50 != 0) {
      var number = 62 / 50 + 1 // adding 1 is doing the actual "round up"
  }

숫자 는 값 2를 포함

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.