我正在尝试翻译此代码段:
ntohs(*(UInt16*)VALUE) / 4.0
从C到斯威夫特,其他一些看起来相似的东西。
问题是,我对Swift知之甚少,而我无法理解这段代码的作用......以下是我所知道的:
ntohs
swap endianness to host endianness VALUE
是char[32]
(UInt(data.0) << 6) + (UInt(data.1) >> 2)
做同样的事情。可以解释一下吗?Uint
(UInt64
)谢谢!
答案 0 :(得分:7)
VALUE
是指向32个字节(char[32]
)的指针。UInt16
指针。这意味着VALUE
的前两个字节被解释为UInt16
(2个字节)。*
将取消引用指针。我们得到VALUE
的两个字节作为16位数。但是它有net endianness(净字节顺序),所以我们不能对它进行整数运算。4.0
。要在Swift中执行相同操作,我们只需将字节值组合为整数。
let host = (UInt(data.0) << 8) | UInt(data.1)
请注意,要除以4.0
,您必须将整数转换为Float
。
答案 1 :(得分:2)
你引用的C在技术上是不正确的,虽然它将按照大多数生产C编译器的预期编译.¹实现相同效果的更好方法,也应该更容易转换为Swift,
unsigned int val = ((((unsigned int)VALUE[0]) << 8) | // ² ³
(((unsigned int)VALUE[1]) << 0)); // ⁴
double scaledval = ((double)val) / 4.0; // ⁵
第一个语句读取VALUE
的前两个字节,将它们解释为网络字节顺序中的16位无符号数,并将它们转换为主机字节顺序(无论这些字节顺序是否不同)。第二个语句将数字转换为double
并对其进行缩放。
¹具体来说,*(UInt16*)VALUE
会引发未定义的行为,因为它违反了基于类型的别名规则,即非对称:带有字符类型的指针可用于访问任何类型的对象,但是具有任何其他类型的指针可能不用于访问具有(array-of-)字符类型的对象。
²在C中,为了使后续的移位和or-ing以无符号类型发生,这里需要转换为unsigned int
。如果您转换为uint16_t
,这似乎更合适,那么“通常的算术转换”会在执行左移之前将其转换为已签名的int
。这会在int
仅为16位宽的系统上引发未定义的行为(不允许您转换到符号位)。对于具有小范围的类型,Swift几乎肯定具有完全不同的算法规则;你可能需要在轮班之前投出某事,但我不能告诉你什么。
³我对这个表达式进行了过度括号化,这样即使你对C语言并不十分熟悉,操作的顺序也会很清楚。
⁴左移零位无效;它仅包含在并行结构中。
C在C中不需要在除法运算之前显式转换为double
,但它在Swift中,所以我在这里写了这个。
答案 2 :(得分:-2)
看起来代码采用单字节值[0]。然后取消引用,这应该从低内存地址1到127(可能是255)检索一个数字。 那么什么数字除以4。
我真的不敢相信我的解释是正确的,不能检查我没有笔记本电脑。我真的认为你的代码中可能存在拼写错误,因为它不是一件好事。便携式,可重复使用
我必须强调字符串不会转换为数字。然后使用