Swift-소수점이 0과 같으면 부동 소수점에서 소수점을 제거하는 방법?


88

소수점 하나로 거리를 표시하고 있는데, 0 (예 : 1200.0Km) 인 경우이 소수점을 제거하고 싶습니다. 어떻게 신속하게 할 수 있습니까? 이 번호를 다음과 같이 표시합니다.

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: "%.1f", distanceFloat) + "Km"

답변:


137

스위프트 3/4 :

var distanceFloat1: Float = 5.0
var distanceFloat2: Float = 5.540
var distanceFloat3: Float = 5.03

extension Float {
    var clean: String {
       return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }
}

print("Value \(distanceFloat1.clean)") // 5
print("Value \(distanceFloat2.clean)") // 5.54
print("Value \(distanceFloat3.clean)") // 5.03

Swift 2 (원래 답변)

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
distanceLabel.text = String(format: distanceFloat == floor(distanceFloat) ? “%.0f" : "%.1f", distanceFloat) + "Km"

또는 확장 :

extension Float {
    var clean: String {
        return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
    }
}

나는 전에이 줄을 추가 distanceFloat = floor(distanceFloat * 10) / 10한 다음이 :) 완벽 덕분에 일
칼리 Aney을

1
Double의 경우 확장 Double {var clean : String {return self % 1 == 0? 문자열 (형식 : "%는 .0d"자기) : 문자열 (자기)}}
Abo3atef

3
플로트가 3.01과 같은 경우 작동하지 않습니다.
chengsam

음수는 어떻습니까?
Happiehappie

이 123456738.0 번호에서는 작동하지 않습니다. 변환 된 번호는 123456736으로 표시됩니다.
Anirudha Mahale 19

116

NSNumberFormatter 사용 :

let formatter = NumberFormatter()
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = 2

// Avoid not getting a zero on numbers lower than 1
// Eg: .5, .67, etc...
formatter.numberStyle = .decimal

let nums = [3.0, 5.1, 7.21, 9.311, 600.0, 0.5677, 0.6988]

for num in nums {
    print(formatter.string(from: num as NSNumber) ?? "n/a")
}

보고:

5.1

7.21

9.31

600

0.57

0.7


2
완벽 해! 이것은 맨 위에 있어야합니다
GoodSp33d

6
Swift 3 : let formatter = NumberFormatter() formatter.minimumFractionDigits = 0 formatter.maximumFractionDigits = 1 statLabel.text = formatter.string(from: value as NSNumber) ?? "n/a"
alexxjk

1
약 0.3000, 나는 이것을 시도해 .3; 스타일을 설정했습니다formatter.numberStyle = .decimal
stan liu

@stanliu는 정확합니다. .decimal숫자를 추가하지 않으면 1 미만 의 스타일 번호는 0없이 표시됩니다. 예 : .5, .78 등 ... 지금 답변 수정 중.
HotFudgeSunday

나는 이것이 그러한 문제를 해결하려는 애플의 의도라고 믿는다.
DragonCherry

55

extension 이를 수행하는 강력한 방법입니다.

확장 :

Swift 2 용 코드 (Swift 3 이상 아님) :

extension Float {
    var cleanValue: String {
        return self % 1 == 0 ? String(format: "%.0f", self) : String(self)
    }
}

사용법 :

var sampleValue: Float = 3.234
print(sampleValue.cleanValue)

3.234

sampleValue = 3.0
print(sampleValue.cleanValue)

sampleValue = 3
print(sampleValue.cleanValue)


샘플 플레이 그라운드 파일은 여기에 있습니다 .


1
하지만 3.230000-> 3.230000 ... "-> 3.23"은 어떻습니까?
CHiP-love-NY

1
@ CHiP-love-NY, 나는 당신을 얻지 못했습니다.
Ashok 2011 년

1
나는 그가 당신의 확장이 후행 0을 제거하지 않는다고 생각한다고 믿습니다. String (3.230000) = "3.23"
jeffjv

34

신속한 3에 대한 수락 된 답변 업데이트 :

extension Float
{
    var cleanValue: String
    {
        return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }
}

사용법은 다음과 같습니다.

let someValue: Float = 3.0

print(someValue.cleanValue) //prints 3

예를 들면 작동하지 않습니다. 14.000005, 14.0으로 변환
Vetuka

@ sc13 허, 이상합니다. 14.00000005로 푸시하면 float 자체가 'cleanValue'없이 14를 반환합니다. 이것이 Float를 신속하게 처리하는 방법과 관련이 있다고 생각하십시오. 그 버그를 고칠 수 있는지 보러 갈 것입니다.
크리스토퍼 라센

2
14.000005에 대한 올바른 출력을 얻었으므로 @ sc13 주석이 쓸모 없거나 잘못된 것 같습니다.
Cœur

10

문자열로 형식을 지정하려면 다음 패턴을 따르십시오.

let aFloat: Float = 1.123

let aString: String = String(format: "%.0f", aFloat) // "1"
let aString: String = String(format: "%.1f", aFloat) // "1.1"
let aString: String = String(format: "%.2f", aFloat) // "1.12"
let aString: String = String(format: "%.3f", aFloat) // "1.123"

Int로 캐스트하려면 다음 패턴을 따르십시오.

let aInt: Int = Int(aFloat) // "1"

String(format:이니셜 라이저 를 사용하면 Swift는 다음 숫자를 기준으로 필요에 따라 최종 숫자를 자동으로 반올림합니다.


값이 1.678 인 경우 작동하지 않습니다
Saurav Nagpal

@SauravNagpal 그것은 작동합니다 :)
Baig

9

이미 언급 한대로 확장을 사용할 수 있지만이 솔루션은 조금 더 짧습니다.

extension Float {
    var shortValue: String {
        return String(format: "%g", self)
    }
}

사용 예 :

var sample: Float = 3.234
print(sample.shortValue)

1
에 대해 실패합니다 0.00000001. pubs.opengroup.org/onlinepubs/009695399/functions/printf.html 에서 % g 문서를 참조하십시오 . " 사용 된 스타일은 변환 된 값에 따라 다릅니다. 스타일 e (또는 E)는 이러한 변환의 결과 인 지수 인 경우에만 사용됩니다. -4보다 작거나 정밀도보다 크거나 같습니다. "
Cœur

완전한. 감사합니다
PhillipJacobs

7

에서 스위프트 4는 이것을 시도.

    extension CGFloat{
        var cleanValue: String{
            //return String(format: 1 == floor(self) ? "%.0f" : "%.2f", self)
            return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(format: "%.2f", self)//
        }
    }

// 사용 방법-(.) 포인트 뒤에 2 자 이상 입력하면 자동으로 마지막 문자를 잘라 내고 포인트 뒤에 2 자만 표시합니다.

let strValue = "32.12"
print(\(CGFloat(strValue).cleanValue)

값에서 0을 잘라 내지 않습니다 1.1. 출력이됩니다 "1.10".
Cœur

@ Cœur 포인트 (.) 뒤에 두 값을 표시하는 데 사용됩니다. 하나의 값만 표시하려면 "return self.truncatingRemainder (dividingBy : 1) == 0? String (format :"% .0f ", self) : String (format :"% .1f ", self) / / "
Jaydip

알아 ... 당신의 코드가 다른 답변 동작과 어떻게 다른지 설명하고 있었어요.
Cœur

4

NSNumberFormatter는 당신의 친구입니다

let distanceFloat: Float = (currentUser.distance! as NSString).floatValue
let numberFormatter = NSNumberFormatter()
numberFormatter.positiveFormat = "###0.##"
let distance = numberFormatter.stringFromNumber(NSNumber(float: distanceFloat))!
distanceLabel.text = distance + " Km"

4

후행 0없이 최대 분수 자릿수로 서식 지정

이 시나리오는 사용자 정의 출력 정밀도가 필요할 때 유용합니다. 이 솔루션은 MirekE의 NumberFormatter + NSNumber 솔루션 만큼 빠르지 만 한 가지 이점은 여기서 NSObject를 피하고 있다는 것입니다.

extension Double {
    func string(maximumFractionDigits: Int = 2) -> String {
        let s = String(format: "%.\(maximumFractionDigits)f", self)
        var offset = -maximumFractionDigits - 1
        for i in stride(from: 0, to: -maximumFractionDigits, by: -1) {
            if s[s.index(s.endIndex, offsetBy: i - 1)] != "0" {
                offset = i
                break
            }
        }
        return String(s[..<s.index(s.endIndex, offsetBy: offset)])
    }
}

(에서도 작동 extension Float하지만 macOS 전용 유형에서는 작동 하지 않음Float80 )

용법: myNumericValue.string(maximumFractionDigits: 2) 또는myNumericValue.string()

출력 maximumFractionDigits: 2:

1.0 → "1"
0.12 → "0.12"
0.012 → "0.01"
0.0012 → "0"
0.00012 → "0"


4

Double 용 Swift 5는 @Frankie의 float에 대한 답변과 동일합니다.

var dec: Double = 1.0
dec.clean // 1

연장을 위해

extension Double {
    var clean: String {
       return self.truncatingRemainder(dividingBy: 1) == 0 ? String(format: "%.0f", self) : String(self)
    }

}

3

다음은 전체 코드입니다.

let numberA: Float = 123.456
let numberB: Float = 789.000

func displayNumber(number: Float) {
    if number - Float(Int(number)) == 0 {
        println("\(Int(number))")
    } else {
        println("\(number)")
    }
}

displayNumber(numberA) // console output: 123.456
displayNumber(numberB) // console output: 789

여기에 가장 중요한 라인이 있습니다.

func displayNumber(number: Float) {
  1. float의 10 진수를 Int(number).
  2. 를 사용하여 작업을 수행하기 위해 제거 된 숫자를 다시 float로 반환합니다 Float(Int(number)).
  3. 십진수 값을 가져옵니다. number - Float(Int(number))
  4. 십진수 값이 비어 있는지 확인합니다. if number - Float(Int(number)) == 0

if 및 else 문의 내용은 설명 할 필요가 없습니다.


귀하의 경우 String에는 println(result)do 대신 함수를 반환하고 싶을 것 return result입니다. 이게 도움이 되길 바란다!
좋은 사람

3

단순함 :

Int(floor(myFloatValue))

이것은 항상 소수점을 제거하지 않습니까? OP는 그것을 원하지 않습니다.
Rakesha Shastri

2

이것도 도움이 될 수 있습니다.

extension Float {
    func cleanValue() -> String {
        let intValue = Int(self)
        if self == 0 {return "0"}
        if self / Float (intValue) == 1 { return "\(intValue)" }
        return "\(self)"
    }
}

용법:

let number:Float = 45.23230000
number.cleanValue()

-1

어쩌면 stringByReplacingOccurrencesOfString당신을 도울 수 있습니다 :)

let aFloat: Float = 1.000

let aString: String = String(format: "%.1f", aFloat) // "1.0"

let wantedString: String = aString.stringByReplacingOccurrencesOfString(".0", withString: "") // "1"

이 값은
1.05-

@Starceaker 아니요, 먼저 1.05실행 하면 작동합니다. 경우 것이 실행 됩니다 ,이해야보다String(format: "%.1f", aFloat)1.01.05String(format: "%.2f", aFloat)1.05stringByReplacingOccurrencesOfString(".00"...)
레오

맞습니다. 마지막 줄에 집중했습니다. 몇 가지 해결책을 제안했다고 생각했지만 실제로는 회선이 연결되어 있습니다. 내 잘못이야.
Starceaker

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