Swift – удалить конечные нули из двойного

Какая функция удаляет конечные нули из двойных чисел?

var double = 3.0
var double2 = 3.10

println(func(double)) // 3
println(func(double2)) // 3.1

person Bogdan Bogdanov    schedule 10.04.2015    source источник
comment
double не имеет завершающих нулей, только его строковое представление. Посмотрите на NSNumberFormatter или String(format: ...). Здесь, на SO, уже должно быть несколько примеров для обоих.   -  person Martin R    schedule 10.04.2015
comment
Вы также можете использовать numberFormatter, как в этом примере: /30664610" title="строка формата с удаленными завершающими нулями для x знаков после запятой в swift"> stackoverflow.com/questions/30663996/   -  person wolffan    schedule 11.01.2018


Ответы (5)


В Swift 4 вы можете сделать это так:

extension Double {
    func removeZerosFromEnd() -> String {
        let formatter = NumberFormatter()
        let number = NSNumber(value: self)
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = 16 //maximum digits in Double after dot (maximum precision)
        return String(formatter.string(from: number) ?? "")
    }
}

пример использования: print (Double("128834.567891000").removeZerosFromEnd()) результат: 128834.567891

Вы также можете подсчитать, сколько десятичных цифр содержит ваша строка:

import Foundation

extension Double {
    func removeZerosFromEnd() -> String {
        let formatter = NumberFormatter()
        let number = NSNumber(value: self)
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = (self.components(separatedBy: ".").last)!.count
        return String(formatter.string(from: number) ?? "")
    }
}
person Grzegorz R. Kulesza    schedule 31.08.2018
comment
он преобразует 0,517 в 0,517. что не могло быть требованием нескольких людей - person Sandeep Dhull; 20.06.2019
comment
Я думаю, вы можете просто использовать formatter.minimumIntegerDigits = 1 в этом случае. - person Software Engineer; 20.03.2020

Вы можете сделать это так, но он вернет строку:

var double = 3.0
var double2 = 3.10

func forTrailingZero(temp: Double) -> String {
    var tempVar = String(format: "%g", temp)
    return tempVar
}

forTrailingZero(double)   //3
forTrailingZero(double2)  //3.1
person Dharmesh Kheni    schedule 10.04.2015
comment
Обратите внимание, что формат %g переключается на экспоненциальное представление, если число становится слишком большим: forTailingZero(123456789) == 1.23457e+08 :) - person Martin R; 10.04.2015
comment
Я думаю, что более оптимальное решение описано в этом ответе: stackoverflow.com/a/30664610/2859764 - person Akshit Zaveri; 26.02.2017

Удаление завершающих нулей в выводе

Этот сценарий хорош, когда требуется точность вывода по умолчанию. Мы проверяем значение на возможные нули в конце и используем другой формат вывода в зависимости от этого.

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

(работает также с extension Float, но не с Float80)

Выход:

1,0 → 1
0,1 → 0,1
0,01 → 0,01
0,001 → 0,001
0,0001 → 0,0001

Форматирование с максимальным числом дробей, без завершающих нулей

Этот сценарий хорош, когда требуется пользовательская точность вывода. Это решение кажется примерно таким же быстрым, как NumberFormatter + NSNumber решение от MirekE, но одним из преимуществ может быть то, что мы избегаем NSObject здесь .

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

(работает также с extension Float, но не с Float80)

Вывод для maximumFractionDigits: 2:

1,0 → 1
0,12 → 0,12
0,012 → 0,01
0,0012 → 0
0,00012 → 0

Обратите внимание, что он выполняет округление (так же, как решение MirekE):

0,9950000 → 0,99
0,9950001 → 1

person Cœur    schedule 17.09.2018
comment
когда maximumFractionDigits = 0, 254,99998480081558 ==> 25 - person hstdt; 21.07.2020

Если вы ищете, как удалить конечные нули из строки:

string.replacingOccurrences(of: "^([\d,]+)$|^([\d,]+)\.0*$|^([\d,]+\.[0-9]*?)0*$", with: "$1$2$3", options: .regularExpression)

Это преобразует такие строки, как 0,123000000, в 0,123.

person Ilya Shevyryaev    schedule 17.07.2020
comment
Самый простой способ обычно самый простой. - person user-44651; 03.03.2021
comment
если на входе 63.00, на выходе будет 63. что неверно - person Saranjith; 19.07.2021
comment
@Saranjith попробуйте мой обновленный ответ - person Ilya Shevyryaev; 20.07.2021

Все ответы, которые я нашел, были хорошими, но все они имели некоторые проблемы, такие как создание десятичных чисел без 0 в начале (например, .123 вместо 0.123). но эти два сделают работу без проблем:

extension Double {
    func formatNumberWithFixedFraction(maximumFraction: Int = 8) -> String {
        let stringFloatNumber = String(format: "%.\(maximumFraction)f", self)
        return stringFloatNumber
    }
    
    func formatNumber(maximumFraction: Int = 8) -> String {
        let formatter = NumberFormatter()
        let number = NSNumber(value: self)
        formatter.minimumFractionDigits = 0
        formatter.maximumFractionDigits = maximumFraction
        formatter.numberStyle = .decimal
        formatter.allowsFloats = true
        let formattedNumber = formatter.string(from: number).unwrap
        return formattedNumber
    }
}

Первый преобразует 71238.12 с maxFraction 8 в: 71238.12000000, а второй с maxFraction 8 преобразует его в: 71238.12

person Mehrdad    schedule 16.01.2021