【问题标题】:Unsigned versus signed numbers as indexes无符号与有符号数字作为索引
【发布时间】:2011-03-04 20:31:39
【问题描述】:

在 .Net 中使用有符号数作为索引的基本原理是什么?

在 Python 中,您可以通过发送负数从数组末尾开始索引,但在 .Net 中并非如此。 .Net 以后添加这样的功能并不容易,因为它可能会在索引时使用特殊规则(是的,一个坏主意,但我猜它会发生)破坏其他代码。

并不是说我曾经需要索引超过 2,147,483,647 大小的数组,但我真的不明白他们为什么选择有符号数字。

可能是因为在代码中使用带符号的数字更正常吗?

编辑:我刚刚找到这些链接:

The perils of unsigned iteration in C/C++

Signed word lengths and indexes

Edit2:好的,Matthew Flaschen 发布的线程中还有其他几个很好的理由:

  • 历史原因,因为它是一种类似 c 的语言
  • 与 c 互操作

【问题讨论】:

标签: .net unsigned signed indexing


【解决方案1】:

这可能是使用低于 0 的值作为无效索引的悠久传统。如果找不到元素,则 String.IndexOf 之类的方法返回 -1。因此,必须对返回值进行签名。如果 index-consumers 需要无符号值,则您必须 a) 检查并 b) 转换该值以使用它。使用签名索引,您只需要检查即可。

【讨论】:

  • 似乎有道理,但这是我能想到的唯一例子。使用负数作为索引是运行时错误。 IndexOf 可以用另一种方式实现。
  • 另一个例子是List<T>.BinarySearch,如果找到项目,则返回“排序列表中项目的从零开始的索引;否则,一个负数,它是下一个大于 item 的元素的索引,如果没有更大的元素,则为 Count 的按位补码。"
【解决方案2】:

当然是为了简单。你喜欢trouble 用无符号整数做大小运算吗?

【讨论】:

  • 您发布的示例是不良编程实践的完美示例。如果某人是这样的业余编码员,那么即使有符号整数也无法将他从缓冲区不足/溢出中拯救出来。
【解决方案3】:

未签名不符合 CLS。

【讨论】:

  • 但是微软制定的 CLS 规范对吗?在这种情况下,他们拥有最终决定权,并且他们确实选择使用带符号的数字。
  • @Blindy:我认为他们想让 CLS 规范尽可能具有包容性,并且并非所有语言都支持无符号数字(例如 VB6,即使 VB6 不是 CLS 语言,我想他们可能想要增加互操作性的机会)。
  • @Blindy:Java 甚至没有未签名的。
【解决方案4】:

无符号数的主要用途在于将较小的数字组合成较大的数字,反之亦然。例如,如果一个人从一个连接中接收到四个无符号字节,并希望将它们的值作为一个整体视为一个 32 位整数,那么使用无符号类型意味着我们可以简单地说:

值 = 字节 0 | (字节1*256) | (字节2*65536) | (字节3*16777216);

相比之下,如果字节是有符号的,像上面这样的表达式会更复杂。

我不确定我是否真的看到现在设计的语言不包含比最长有符号整数类型更短的所有类型的无符号版本的任何理由,其语义是所有整数(意思是离散数量数字,而不是默认情况下,将执行完全适合最大带符号类型的任何特定类型)操作就好像它们正在对该类型进行操作。包含最大有符号类型的无符号版本会使语言规范复杂化(因为必须指定哪些操作必须适合有符号类型的范围,哪些操作必须适合无符号类型的范围),否则应该有即使unsigned2 大于unsigned1 [如果想要无符号环绕,可以明确指定if ((Uint32)(unsigned1 - unsigned2) &gt; unsigned3)],设计一门语言也没有问题。指定这种行为的语言肯定会比 C(鉴于其历史是合理的)、C# 或 vb.net 中存在的混乱情况有很大的改进。

【讨论】:

    猜你喜欢
    • 2010-09-29
    • 1970-01-01
    • 2010-09-19
    • 2016-07-05
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 2014-12-26
    相关资源
    最近更新 更多