【发布时间】:2014-09-19 02:43:55
【问题描述】:
如何快速创建一个接受任何类型的 Int 或 Uint 的函数 (以及计算参数类型所需的位数)
【问题讨论】:
如何快速创建一个接受任何类型的 Int 或 Uint 的函数 (以及计算参数类型所需的位数)
【问题讨论】:
String 有构造函数
init<T : _SignedIntegerType>(_ v: T, radix: Int, uppercase: Bool = default)
init<T : _UnsignedIntegerType>(_ v: T, radix: Int, uppercase: Bool = default)
可以在这里使用:
let num = 100
let str = String(num, radix: 2)
print(str)
// Output: 1100100
【讨论】:
这是一个较短的版本。但它不会添加额外的前导零:
func bitRep<T: IntegerArithmeticType>(value: T) -> String {
var n: IntMax = value.toIntMax()
var rep = ""
while(n > 0){
rep += "\(n % 2)"
n = n / 2;
}
return rep
}
【讨论】:
IntegerArithmetic 在当前的 beta 版本中被称为 IntegerArithmeticType,我冒昧地编辑了您的代码以使其再次编译。 - 但请注意,您的函数返回反转的字符串,例如bitRep(8) = "0001" 而不是 "1000"。
let binStr:Int->String = {a in return String(a, radix: 2)}
binStr(7) // "111"
【讨论】:
这是一个使用泛型的函数,以便接受任何类型的 Int 或 Uint 而无需参数转换。
1- 函数需要约束一个符合“ToInt”协议的值类型 为了提供一种将 self 类型转换为 Int 的独特方法
2- 函数根据参数类型计算长度位需求
3- 该功能每 8 位插入空格以提供易读性
protocol ToInt { func toInt() -> Int }
extension UInt: ToInt { func toInt() -> Int { return Int(self) } }
extension Int8: ToInt { func toInt() -> Int { return Int(self) } }
extension UInt8: ToInt { func toInt() -> Int { return Int(self) } }
extension Int16: ToInt { func toInt() -> Int { return Int(self) } }
extension UInt16: ToInt { func toInt() -> Int { return Int(self) } }
extension Int32: ToInt { func toInt() -> Int { return Int(self) } }
extension UInt32: ToInt { func toInt() -> Int { return Int(self) } }
extension Int64: ToInt { func toInt() -> Int { return Int(self) } }
extension UInt64: ToInt { func toInt() -> Int { return Int(self) } }
func bitRep<T:ToInt>(value: T) -> String {
var size: Int
switch value {
case is Int8, is UInt8: size = 7
case is Int16, is UInt16: size = 15
case is Int32, is UInt32: size = 31
case is Int64, is UInt64: size = 63
default : size = 63
}
var n = value.toInt()
var rep = ""
for (var c = size; c >= 0; c--) {
var k = n >> c
if (k & 1) == 1 { rep += "1" } else { rep += "0" }
if c%8 == 0 && c != 0 { rep += " " }
}
return rep
}
一些例子:
let b1: UInt8 = 0b00000000
bitRep(b1)
// > "00000000"
let c1: UInt16 = 0b00000000_10000101
bitRep(c1)
// > "00000000 10000101"
let e1: UInt64 = 0b00000000_00000000_00000000_00000001
bitRep(e1)
// > "00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000001"
等等!
(算法灵感来自此线程:Turning an integer to its binary representation using C?)
【讨论】:
toInt的原因是什么? Int(value) 会做同样的事情,但它仍然不适用于大于 Int.max 的整数
Int(value),所以你需要一些约束才能使用。
Integer 或者我现在想不起来的东西)