将双精度值四舍五入为快速小数位数的x位

vwoqyblh  于 2022-09-19  发布在  Swift
关注(0)|答案(30)|浏览(264)

谁能告诉我如何在SWIFT中将双精度值舍入到小数点后x位?

我有:

var totalWorkTimeInHours = (totalWorkTime/60/60)

其中totalWorkTime为NSTimeInterval(双精度),单位为秒。

totalWorkTimeInHours会给我小时数,但它给了我如此长的精确数字中的时间量,例如1.543240952039......

当我打印totalWorkTimeInHours时,如何将其四舍五入为1.543?

wd2eg0qa

wd2eg0qa1#

我会用

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

并将.3f更改为所需的任意十进制数

7fhtutme

7fhtutme2#

很多例子都使用数学,问题是浮点数是实数的近似值,没有办法将0.1(1/10)精确地表示为浮点数,就像没有确切的方法使用小数点来精确地表示⅓一样,所以您需要问问自己您到底想要实现什么,如果您只想显示它们,将它们保留在代码中,尝试对它们进行舍入会给出不太准确的结果,因为您正在丢弃宝贵的十进制记数法将⅓舍入到1小数位数不会给出一个更接近⅓的数字,我们使用数字进行舍入。如果您有类似于viewModel类的东西,则可以使用它将字符串表示返回到您的模型编号。NumberFormaters让您可以很好地控制如何格式化数字以及您想要的小数位数。

3vpjnl9f

3vpjnl9f3#

//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"
eulz3vhy

eulz3vhy4#

这个解决方案对我很管用。Xcode 13.3.1和SWIFT 5

extension Double {

    func rounded(decimalPoint: Int) -> Double {
        let power = pow(10, Double(decimalPoint))
       return (self * power).rounded() / power
    }
}

测试:

print(-87.7183123123.rounded(decimalPoint: 3))
print(-87.7188123123.rounded(decimalPoint: 3))
print(-87.7128123123.rounded(decimalPoint: 3))

结果:

-87.718
-87.719
-87.713
zxlwwiss

zxlwwiss5#

如果您需要一个带有Numer值的文本元素,这里有一个用于SwiftUI的。

struct RoundedDigitText : View {
    let digits : Int
    let number : Double

    var body : some View {
        Text(String(format: "%.(digits)f", number))
    }
}
ntjbwcob

ntjbwcob6#

您可以添加此扩展名:

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
yi0zb3m4

yi0zb3m47#

我在想是否可以更正用户的输入时发现了这一点。也就是说,如果他们输入三个小数,而不是两个小数来表示美元金额。比方说1.111而不是1.11,你能四舍五入算出来吗?原因很多,答案是否定的!有了钱,任何超过0.001的钱最终都会在真正的支票簿上引起问题。

下面是一个函数,用于检查用户输入的值在该期间之后是否过多。但这将允许1.,1.1和1.11。

假设已经检查了该值是否成功从字符串转换为双精度值。

//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

}
vs3odd8k

vs3odd8k8#

var n = 123.111222333
n = Double(Int(n * 10.0)) / 10.0

结果:n=123.1

将10.0(小数点后1位)更改为100.0(小数点后2位)、1000.0(小数点后3位)中的任意一个,依此类推,以获得小数点后所需的位数。

pobjuy32

pobjuy329#

要避免浮点型缺陷,请使用Decimal

extension Float {
    func rounded(rule: NSDecimalNumber.RoundingMode, scale: Int) -> Float {
        var result: Decimal = 0
        var decimalSelf = NSNumber(value: self).decimalValue
        NSDecimalRound(&result, &decimalSelf, scale, rule)
        return (result as NSNumber).floatValue
    }
}

例如:

在比例为2和.Down的情况下使用浮点时,1075.58舍入为1075.57
小数位数为2和.Down时,1075.58舍入为1075.58

puruo6ea

puruo6ea10#

SWIFT 5

使用字符串方法

var yourDouble = 3.12345
//to round this to 2 decimal spaces i could turn it into string
let roundingString = String(format: "%.2f", myDouble)
let roundedDouble = Double(roundingString) //and than back to double
// result is 3.12

但使用扩展名更容易被接受

extension Double {
    func round(to decimalPlaces: Int) -> Double {
        let precisionNumber = pow(10,Double(decimalPlaces))
        var n = self // self is a current value of the Double that you will round
        n = n * precisionNumber
        n.round()
        n = n / precisionNumber
        return n
    }
}

然后您可以使用:

yourDouble.round(to:2)
tvz2xvvm

tvz2xvvm11#

这似乎在SWIFT 5中奏效。

令人惊讶的是,目前还没有针对此的标准函数。

//使用四舍五入将双精度小数位截断为n位小数

extension Double {

    func truncate(to places: Int) -> Double {
    return Double(Int((pow(10, Double(places)) * self).rounded())) / pow(10, Double(places))
    }

}
ugmeyewa

ugmeyewa12#

不是斯威夫特,但我相信你会明白的。

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

j2cgzkjk13#

将双精度值四舍五入为x位小数

不是的。小数点后的位数

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
7cwmlq89

7cwmlq8914#

设置双精度属性格式的最佳方法是使用Apple预定义方法。

mutating func round(_ rule: FloatingPointRoundingRule)

FloatingPointRoundingRule是具有以下可能性的枚举

枚举案例:

Case awayFromZero舍入为大于或等于源的最接近允许值。

大小写向下四舍五入到最接近的允许值,小于或等于源。

Case to NearestOr Away FromZero舍入到最接近的允许值;如果两个值同样接近,则选择幅度较大的那个。

Case to NearestOrEven舍入到最接近的允许值;如果两个值相等,则选择偶数。

case to ardZero四舍五入为最接近的允许值,其数值小于或等于震源的数值。

大小写向上四舍五入到大于或等于源的最接近的允许值。

var aNumber : Double = 5.2
aNumber.rounded(.up) // 6.0
xghobddn

xghobddn15#

这是更灵活的舍入到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

相关问题