在Swift

时间:2015-07-14 01:47:54

标签: swift math floating-accuracy

我试图在swift中分隔double的十进制和整数部分。我尝试了很多方法,但它们都遇到了同样的问题...

let x:Double = 1234.5678
let n1:Double = x % 1.0           // n1 = 0.567800000000034
let n2:Double = x - 1234.0        // same result
let n3:Double = modf(x, &integer) // same result

有没有办法获得0.5678而不是0.567800000000034而无需将数字转换为字符串?

10 个答案:

答案 0 :(得分:58)

您可以使用truncatingRemainder1作为分隔符。

  

使用截断除法返回此值的余数除以给定值。

Apple doc

示例:

let myDouble1: Double = 12.25
let myDouble2: Double = 12.5
let myDouble3: Double = 12.75

let remainder1 = myDouble1.truncatingRemainder(dividingBy: 1)
let remainder2 = myDouble2.truncatingRemainder(dividingBy: 1)
let remainder3 = myDouble3.truncatingRemainder(dividingBy: 1)

remainder1 -> 0.25
remainder2 -> 0.5
remainder3 -> 0.75

答案 1 :(得分:13)

如果不将其转换为字符串,您可以将这样的小数位向上舍入:

let x:Double = 1234.5678
let numberOfPlaces:Double = 4.0
let powerOfTen:Double = pow(10.0, numberOfPlaces)
let targetedDecimalPlaces:Double = round((x % 1.0) * powerOfTen) / powerOfTen

您的输出将是

  

0.5678

答案 2 :(得分:10)

Swift 2

您可以使用:

                            $http({
                        method  : 'POST',
                        url     : 'offers.php',
                        data    : $.param(code),  
                        headers : { 'Content-Type': 'application/x-www-form-urlencoded' } 
                        })
                        .success(function(data) 
                          {
                            //display the data somehow...
                         });

// You can also supply a custom validator to `arrayOf` and `objectOf`.
    // It should return an Error object if the validation fails. The validator
    // will be called for each key in the array or object. The first two
    // arguments of the validator are the array or object itself, and the
    // current item's key.
    customArrayProp: React.PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) {
      if (!/matchme/.test(propValue[key])) {
        return new Error(
          'Invalid prop `' + propFullName + '` supplied to' +
          ' `' + componentName + '`. Validation failed.'
        );
      }
    })

答案 3 :(得分:6)

使用Float,因为它的精确数字少于Double

let x:Double = 1234.5678
let n1:Float = Float(x % 1)           // n1 = 0.5678

答案 4 :(得分:1)

与Alessandro Ornano相同的方法实现为FloatingPoint协议的实例属性:

public extension FloatingPoint {
    public var whole: Self { return modf(self).0 }
    public var fraction: Self { return modf(self).1 }
}

1.2.whole    // 1
1.2.fraction // 0.2

答案 5 :(得分:1)

C的数学库中有一个函数,并且许多编程语言(包括Swift)可以让您访问它。它叫做 modf ,在Swift中,它的工作原理如下

// modf返回一个2元素元组,

//,其中整数部分位于第一个元素中,

//和第二个元素中的小数部分

让splitPi = modf(3.141592)

splitPi.0 // 3.0

splitPi.1 // 0.141592

您可以创建如下扩展名,

extension Double {

    func getWholeNumber() -> Double {

        return modf(self).0

    }

    func getFractionNumber() -> Double {

        return modf(self).1

    }

}

答案 6 :(得分:0)

您可以像这样获得Integer部分:

let d: Double = 1.23456e12

let intparttruncated = trunc(d)
let intpartroundlower = Int(d)

trunc()函数将小数点后的部分截断,而Int()函数将四舍五入到下一个较低的值。正数是相同的,但负数是不同的。如果从d中减去截断的部分,则将得到小数部分。

func frac (_ v: Double) -> Double
{
    return (v - trunc(v))
}

您可以像这样获得Double的尾数和指数:

let d: Double = 1.23456e78

let exponent = trunc(log(d) / log(10.0))

let mantissa = d / pow(10, trunc(log(d) / log(10.0)))

对于指数,您的结果将是78;对于尾数,您的结果将是1.23456。

希望这对您有所帮助。

答案 7 :(得分:0)

Swift 5.1

let x:Double = 1234.5678

let decimalPart:Double = x.truncatingRemainder(dividingBy: 1)    //0.5678
let integerPart:Double = x.rounded(.towardZero)                   //1234

这两种方法均返回Double值。

如果您想将整数用作整数部分,则可以使用

Int(x)

答案 8 :(得分:0)

创建适用于所有Doubles的解决方案是不可能的。如果其他答案曾经奏效(我也认为这是不可能的),那么它们将不再适用。

let _5678 = 1234.5678.description.drop { $0 != "." } .description // ".5678"
Double(_5678)  // 0.5678

let _567 = 1234.567.description.drop { $0 != "." } .description // ".567"
Double(_567) // 0.5669999999999999

答案 9 :(得分:0)

extension Double {

    /// Gets the decimal value from a double.
    var decimal: Double {
        Double("0." + string.split(separator: ".").last.string) ?? 0.0
    }
    
    var string: String {
        String(self)
    }
}

这似乎解决了双精度问题。

用法:

print(34.46979988898988.decimal) // outputs 0.46979988898988
print(34.46.decimal) // outputs 0.46