3

最近我在System.Numerics.BigInteger 类型定义中发现了一个奇怪的地方,似乎缺乏理由——这种类型不支持按位运算NOT符(~~~在 F# 中)。虽然 F# 中的其他整数类型允许在 .NET 生态系统中执行位否定和整体操作,但bigint类型缺少对应的~~~运算符。

bigint底层硬件不直接支持的合成类型这一事实并不妨碍它支持其他位运算符,即<<<, >>>, |||, ^^^, 和&&&适应缺少预设位宽的情况。那为什么~~~不能呢?

编辑:感谢Jeppe Stig Nielsen指出我对让操作员准确执行的System.Numerics.BigInteger类型的疏忽。我已相应地更正了原始问题。这让我相信F# 中的运算符无意中忽略了这一点。OnesComplementbitwise NOT~~~bigint

4

2 回答 2

1

我不知道这一定是原因,但是缺少固定宽度意味着它~~~不能满足它通常具有的一些好的特性。例如,应该~~~ 5I是什么?从逻辑上讲,这应该是0x1111...1010(带有无限前缀)。显然我们需要在某处修剪这个前缀。如果我们将结果与输入保持相同的位宽,那么我们就会得到010 = 2结果。但由于前导零无关紧要,相同的逻辑规定~~~ 2I应该是1I. 但随后~~~ (~~~ 5I) <> 5I

于 2013-04-29T19:24:23.063 回答
1

如果我们将缺失bitwise NOT (~~~)运算符定义为bigintas

let inline (~~~) x = bigint.op_OnesComplement x

那么我们将能够检查它关于双重否定的实际属性

let ``Double Negation`` x =
    if ~~~ (~~~ x) <> x then
        failwith "Ka-Boom!!"

``Double Negation`` 0I
``Double Negation`` -1I
``Double Negation`` 9999999999I

全部回归unit德摩根定律

let ``De Morgan's Laws`` p q =
    if not
        ((~~~(p &&& q)) = ((~~~p) ||| (~~~q)) &&
        (~~~(p ||| q)) = ((~~~p) &&& (~~~q)))
    then
        failwith "Ka-Boom!!"

``De Morgan's Laws`` 0I 0I
``De Morgan's Laws`` 0I -1I
``De Morgan's Laws`` -1I 0I

也都回来unit了。

在使用上述代码片段时,观察到的完美代码行为似乎会提示您报告问题bigint ~~~fsbugs@microsoft.com进行更正。

于 2013-05-15T19:25:52.663 回答