【问题标题】:Why bytes in c# are named byte and sbyte unlike other integral types?为什么 c# 中的字节被命名为 byte 和 sbyte 与其他整数类型不同?
【发布时间】:2011-05-17 02:50:09
【问题描述】:

我只是在翻阅规范,发现字节很奇怪。其他是short、ushort、int、uint、long和ulong。为什么用 sbyte 和 byte 来命名而不是 byte 和 ubyte?

【问题讨论】:

  • 在设计类型系统时,CLR 设计团队就这个问题争论不休。如您所见,“字节根据定义是无符号的”队伍赢得了争论。
  • @Eric:谢天谢地。我怀疑那些争论有符号字节的人从未经历过在 Java 中使用它们的痛苦;)

标签: c#


【解决方案1】:

这是一个语义问题。当你想到一个字节时,你通常(至少我会)想到一个 0-255 的 8 位值。这就是byte 的含义。二进制数据不太常见的解释是 -128 到 127 的有符号值 (sbyte)。

对于整数,用有符号值来思考会更直观,这就是基本名称样式所代表的内容。然后,u 前缀允许访问不太常见的无符号语义。

【讨论】:

  • +1。请注意,在 Java 中,byte 的范围是 -128 到 127(并且根本没有无符号类型,除非您计算 char)。
  • 我对 Java 有一些了解,但我仍然认为字节为 0-255(或者更确切地说是 00 到 FF,我几乎从不将它们视为数字)。
【解决方案2】:

没有任何其他形容词的“byte”类型通常是无符号的,而没有任何其他形容词的“int”类型通常是有符号的,原因是无符号的 8 位值通常更实用(因此广泛使用)比有符号字节,但较大类型的有符号整数通常比此类类型的无符号整数更实用(因此被广泛使用)。

有一个共同的语言学原则,如果“事物”有两种类型,“通常”和“不寻常”,那么没有形容词的“事物”一词意味着“通常的事物”;术语“不寻常的事物”用于指代不寻常的类型。遵循该原则,由于无符号 8 位数量比有符号数量使用更广泛,因此没有修饰符的术语“字节”指的是无符号风格。相反,由于较大尺寸的有符号整数比它们的无符号等价物更广泛地使用,因此“int”和“long”等术语指的是有符号的风格。

至于这种使用模式背后的原因,如果一个人对一定大小的数字进行数学运算,除了比较之外,数字是有符号还是无符号通常都无关紧要。有时将它们视为已签名很方便(例如,将 -1 加到数字上而不是加 65535 更自然),但在大多数情况下,声明要签名的数字并不需要编译器的任何额外工作,除非执行比较或将数字扩展到更大的大小。事实上,如果有的话,有符号整数数学可能比无符号整数数学更快(因为无符号整数数学需要在溢出的情况下表现出可预测的行为,而无符号数学则不然)。

相比之下,由于 8 位操作数在对其执行任何数学运算之前必须扩展为“int”类型,因此编译器必须生成不同的代码来处理有符号和无符号操作数;在大多数情况下,有符号操作数将需要比无符号操作数更多的代码。因此,如果 8 位值是有符号还是无符号都无关紧要,使用无符号值通常更有意义。此外,许多较大的类型通常被分解为一个 8 位值的序列,或者从这样的序列中重构。使用 8 位无符号类型比使用 8 位有符号类型更容易进行此类操作。由于这些原因,除其他外,无符号 8 位值比有符号 8 位值更常用。

请注意,在 C 语言中,“char”是一种奇怪的情况,因为 C 字符集中的所有字符都需要转换为非负值(因此使用 8 位 char 类型和 EBCDIC 字符的机器set 必须使“char”无符号),但需要一个“int”来保存“char”可以保存的所有值(因此,“char”和“int”都是 16 位的机器需要具有“ char" 被签名)。

【讨论】:

  • @siride:C# 的遗产是什么?在某种程度上它也适用于非 C 语言,同样的原则实际上更适用于那些。例如,最初的 Apple BASIC 有无符号 8 位和有符号 16 位作为两种可用的数学类型。
  • 相关性很小,因为 C# 有自己的规则和自己的运行时系统,例如检查溢出(在没有汇编技巧或非标准编译器扩展的情况下,在 C 中是不可能的)。无论如何,它与问题无关,因为您对字节为何无符号的解释仅与 C 相关,而不与 C# 相关(在这种情况下,短裤与字节一样适用,但短裤遵循短/超短的正常模式)。
  • @siride:也许我写的答案似乎过于以 C 为中心,但这不是我的意图。多年来,许多语言都有类似的语义,尽管我不确定哪些是先出现的(例如,Pascal 是在最初的 Apple “Integer” BASIC 之前还是之后发明的?我认为这种行为的原因正如我所说:字节是更常用作较大类型的组成部分。另请注意,如果一种语言不检查溢出,则可以使用 lsb+256*msb 将一对字节转换为有符号或无符号整数。如果字节是有符号的,那行不通。
  • @siride:为什么没有人喜欢我的回答,它提供的历史背景比公认的要多?事实上,在 C# 中字节“默认”是无符号的,而其他类型是有符号的,这在很大程度上是历史惯例的结果。
  • -1 问题不在于“什么时候使用有符号与无符号更方便/高效?”,而是关于命名约定。您的回答甚至没有谈到为什么命名不同。
猜你喜欢
  • 2012-08-12
  • 1970-01-01
  • 2016-04-25
  • 2011-05-18
  • 2020-04-22
  • 1970-01-01
  • 1970-01-01
  • 2010-12-13
  • 1970-01-01
相关资源
最近更新 更多