如何将通用类型SignedNumeric转换为Float?

福本修二

我正在创建一些实用程序类,用于存储数值(Int,Float,Double等)。它也具有最小值和最大值。

我需要将值转换为百分比。

因此,我在Playground上编写了以下类:

import UIKit

class Series<T: SignedNumeric> {
    let minValue: T
    let maxValue: T
    var datas: [T] = []

    let range: T

    init(minValue: T, maxValue: T) {
        self.minValue = minValue
        self.maxValue = maxValue
        self.range = (maxValue - minValue)
        self.datas = []
    }

    func percent(value: T) -> Float {
        let v: Float = value as! Float
        let m: Float = minValue as! Float
        let r: Float = range as! Float
        return (v - m) / r
    }
}

let s = Series<Int>(minValue: -100, maxValue: 100)
s.datas = [20, 0, 40, -100, 100]
Float(s.datas[0] - s.minValue) / Float(s.range)
Float(s.datas[1] - s.minValue) / Float(s.range)
Float(s.datas[2] - s.minValue) / Float(s.range)
Float(s.datas[3] - s.minValue) / Float(s.range)
Float(s.datas[4] - s.minValue) / Float(s.range)
s.percent(value: s.datas[0]) // ERROR !!!

当调用s.percent(value:s.datas [0])时,它崩溃了。

如何编写percent()函数?

清扫器

并非每个SignedNumeric都可以转换为Float回想一下,要成为SignedNumeric,您必须能够:

  • 正面和负面
  • 相乘
  • 加减
  • 的大小是ComparableNumeric
  • 可以从整数转换

最后4个要求全部继承自Numeric我们可以轻松地构建自己的类型来执行所有这些操作。这是一个人为的例子:

struct MyNumber: SignedNumeric, Comparable {
    private var secret: [String]
    private var isNegative: Bool
    private var number: Int { secret.count }
    
    static func *= (lhs: inout MyNumber, rhs: MyNumber) {
        lhs = lhs * rhs
    }
    
    static func * (lhs: MyNumber, rhs: MyNumber) -> MyNumber {
        MyNumber(secret: Array(repeating: "", count: lhs.number * rhs.number), isNegative: lhs.isNegative != rhs.isNegative)
    }
    
    init(integerLiteral value: Int) {
        let int = value
        isNegative = int < 0
        secret = Array(repeating: "", count: abs(int))
    }
    
    static func < (lhs: MyNumber, rhs: MyNumber) -> Bool {
        lhs.number < rhs.number
    }
    
    init?<T>(exactly source: T) where T : BinaryInteger {
        guard let int = Int(exactly: source) else {
            return nil
        }
        self.init(integerLiteral: int)
    }
    
    var magnitude: MyNumber {
        MyNumber(secret: secret, isNegative: false)
    }
    
    static func - (lhs: MyNumber, rhs: MyNumber) -> MyNumber {
        if lhs < rhs {
            return -(rhs - lhs)
        } else {
            return MyNumber(secret: Array(repeating: "", count: lhs.number - rhs.number))
        }
    }
    
    prefix static func - (operand: MyNumber) -> MyNumber {
        MyNumber(secret: operand.secret, isNegative: !operand.isNegative)
    }
    
    mutating func negate() {
        isNegative.toggle()
    }
    
    init(secret: [String], isNegative: Bool = false) {
        self.secret = secret
        self.isNegative = isNegative
    }
    
    typealias Magnitude = MyNumber
    
    static func + (lhs: MyNumber, rhs: MyNumber) -> MyNumber {
        MyNumber(secret: lhs.secret + rhs.secret)
    }
    
    typealias IntegerLiteralType = Int
    
}

<插入在这里进行转换的人>到底是怎么知道要转换MyNumberFloat,它必须做的Float(aMyNumber.secret.count)呢?更不用说这secret是私人的。

另一方面,Float.init确实知道如何将BinaryFloatingPoints和BinaryIntegers转换Float,因为那些协议定义了必要的属性,以便Float.init可以理解它们的表示方式。例如,BinaryIntegerS被表示words,这是一个RandomAccessCollectionUIntS,由索引Int秒。

我建议您只将该percent方法添加Series实际有意义的类型中

extension Series where T : BinaryInteger {
    func percent(value: T) -> Float {
        let v: Float = Float(value)
        let m: Float = Float(minValue)
        let r: Float = Float(range)
        return (v - m) / r
    }
}

海事组织,这对任何人都有意义T : FloatingPoint,而不仅仅是T : BinaryFloatingPoint

extension Series where T : FloatingPoint {
    func percent(value: T) -> T {
        let v = value
        let m = minValue
        let r = range
        return (v - m) / r
    }
}

由于也FloatingPoint支持除法,因此您无需转换为Float

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何将字符串转换为通用类型

如何将通用数字类型“ T”转换为CGFloat

如何将类对象转换为通用对象类型?

如何将通配符(?)转换为通用类型T?

如何将PostgreSQL 9.4的jsonb类型转换为float

如何将类型化的值转换为通用类型T?

如何将NSString转换为Float

如何将通用类型的数据列表转换为另一个通用类型的数据列表

如何将 float 类型的 numpy 数组转换为 int 类型的 numpy 数组?

Julia:如何将字符串类型的向量转换为数字类型(Float64)

如何将array.map()。toList转换为通用类型?

如何将锡兰序列或数组转换为具有适当类型的通用元组?

VS 2013 Winform应用程序:如何将通用对象转换为按钮类型

如何将随机森林算法转换为通用数据类型?

如何将类型转换为值

如何将此函数转换为通用类型?

如何将元组字符串列表的数据类型转换为float

如何将float [] []类型数组转换为“ emxArray_real_T * x”

如何将列的类型从对象转换为float64?

如何将Java原始float转换为Kotlin Float?

对于本示例,我该如何将需要特定类型参数的现有代码转换为通用类型参数?

如何将通用区分联盟转换为obj

如何将方法转换为通用变体?

如何将通用HList转换为列表

如何将NSMutableOrderedSet转换为通用数组?

如何将数据行转换为通用模型类?

如何将通用T转换为TObject?

如何将DataTable转换为通用列表?

如何将通用IList <T>转换为IList?