在Go中将uint16强制类型转换为int16的正确方法

3
位运算和Go新手: D 我正在使用Go从传感器读取一些数据,并将其作为2个字节接收-假设是0xFFFE。它很容易转换为uint16,因为在Go中我们只需执行uint16(0xFFFE),但我需要将其转换为整数,因为传感器实际上返回范围从-32768到32767的值。现在我想"也许Go会很好,如果我执行int16(0xFFFE),它会理解我的意思吗?",但不行。我最终使用了以下解决方案(我翻译了一些来自Web的Python代码):
x := 0xFFFE

if (x & (1 << 15)) != 0 {
    x = x - (1<<16)
}

看起来它能正常工作,但 A) 我不是完全确定为什么,B) 它看起来有些丑陋,这本应该是将 uint16 转换为 int16 的简单解决方案。有人能帮我澄清为什么这是唯一的方法吗?或者还有其他可能的方法吗?


2
一个小问题:Go语言没有类型转换,而是有类型转换。 - kostix
1个回答

7
但是你想要的是行得通的,“Go很好”:
ui := uint16(0xFFFE)
fmt.Println(ui)
i := int16(ui)
fmt.Println(i)

输出结果(请在Go Playground上尝试):

65534
-2
int16(0xFFFE)无法工作,因为0xfffe是一个未命名的整数常量,不能被表示为int16类型的值,这就是编译器报错的原因。但是你可以将任何uint16非常量的值转换为int16
相关问题请参见以下链接: Golang: on-purpose int overflow Does go compiler's evaluation differ for constant expression and other expression

1
我尝试了一个有点不同的形式 fmt.Println(int16(uint16(0xFFFE))),它抛出了溢出错误。为什么你的例子可以运行呢? - Devligue
2
@Devlige 因为常量值只能在类型可以表示精确值的情况下进行转换。在我的示例中,我不是转换常量,而是变量,其中允许溢出(就像在任何其他语言中一样)。有关详细说明,请参见:Does go compiler's evaluation differ for constant expression and other expression - icza
完美!总的来说,Go确实很好。它只需要更多的知识:) 谢谢 - Devligue
1
@kostix 就在我想要发布链接的时候。该链接包含有关常量的“更多知识”。 - icza
似乎只有使用变量才能实现,如果写成一行代码,会出错:常量65534超出了int16的范围。 - andig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接