.net 为什么bigint在F#中缺少按位NOT运算符(~~~)?

.net 为什么bigint在F#中缺少按位NOT运算符(~~~)?,.net,f#,operator-overloading,biginteger,.net,F#,Operator Overloading,Biginteger,最近,我在System.Numerics.BigInteger中发现了一个奇怪的地方,它似乎缺少对正性-这种类型是按位而不是运算符(~~在F#中)。虽然F#中的其他整数类型允许在.NET生态系统中执行位求反和整体运算,biginttype缺少相应的~运算符 bigint是底层硬件不直接支持的合成类型,这一事实并不妨碍它支持其他按位运算符,即、| |、^^和&&&,以适应预设位宽度的不足。那么为什么~~不能呢 编辑:感谢您指出我对System.Numerics.BigInteger类型的监督,该类

最近,我在
System.Numerics.BigInteger
中发现了一个奇怪的地方,它似乎缺少对正性-这种类型是按位
而不是
运算符(
~~
在F#中)。虽然F#中的其他整数类型允许在.NET生态系统中执行位求反和整体运算,
bigint
type缺少相应的
~
运算符

bigint
是底层硬件不直接支持的合成类型,这一事实并不妨碍它支持其他按位运算符,即
| |
^^
&&&
,以适应预设位宽度的不足。那么为什么
~~
不能呢


编辑:感谢您指出我对
System.Numerics.BigInteger
类型的监督,该类型具有
OneCompletion
运算符,确实执行的是
按位不
。我已相应地更正了原来的问题。这让我相信,F#中的
bigint
操作符无意中省略了
~~~

我不知道这一定是原因,但缺少固定宽度意味着
~~
无法满足它通常所满足的一些良好属性。例如,
~~5I
应该是什么?从逻辑上讲,这应该是
0x1111…1010
(具有无限前缀1)。显然,我们需要在某个地方删掉这个前缀。如果我们将结果保持与输入相同的位宽度,那么我们得到的结果是
010=2
。但是由于前导零并不重要,同样的逻辑规定
~~2I
应该是
1I
。但是如果我们将
bigint
的missing
按位NOT(~~~)
运算符定义为

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
所有返回的
单元也都返回


在处理上述代码片段时,观察到的完美代码行为似乎提示您使用
bigint~~~
fsbugs@microsoft.com
用于更正。

大整数bi1=1;var bi2=~bi1
将是
-2
…您没有仔细查看,因为操作员在您链接的列表中,请参阅。正如@I4V的上述评论所示,该操作符在某些.NET语言中工作良好。所以问题是为什么(显然)F#不支持它?我对F#不太了解,所以我不能回答这个问题。Java的BigInteger类通过保持标识
~x==-1-x
来解决这个问题,所以两个补码表示有一个无限前缀,就像您描述的那样。@finnw.NET确实有这个操作,请参见,问题是F#用于
~~
的符号名是
op_LogicalNot
,而不是
op_onescompletion
,这可能是一个不幸的决定,但现在不会改变。编译器为整数类型合成人工成员(就像它对其他算术运算符所做的那样)。
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