最近我发现虽然F#中的其他整数类型允许在.NET生态系统中执行位否定System.Numerics.BigInteger
type definition中似乎缺乏理由的奇怪 - 这种does not support按位NOT
运算符(~~~
在F#)。和整体,但bigint
类型缺少对应的~~~
运算符。
bigint
是底层硬件不直接支持的合成类型这一事实并不妨碍它支持其他按位运算符,即<<<
,>>>
,|||
,适应缺少预设位宽的^^^
和&&&
。那么为什么~~~
不能呢?
编辑:感谢Jeppe Stig Nielsen指向我对System.Numerics.BigInteger
类型的监督,确实OnesComplement
运算符正好执行bitwise NOT
。我已经相应地纠正了原来的问题。这让我相信F#中的~~~
运算符无意中忽略了bigint
。
答案 0 :(得分:1)
我不知道这是必然的原因,但缺少固定宽度意味着~~~
不会满足它通常所做的一些不错的属性。例如,~~~ 5I
应该是什么?从逻辑上讲,这应该是0x1111...1010
(带有无限前缀的1)。显然我们需要在某个地方修剪这个前缀。如果我们保持结果与输入的位宽相同,那么我们得到010 = 2
作为结果。但由于前导零并不重要,因此同样的逻辑要求~~~ 2I
应为1I
。但接着是~~~ (~~~ 5I) <> 5I
。
答案 1 :(得分:1)
如果我们将bitwise NOT (~~~)
的{{1}}运算符定义为
bigint
然后我们可以检查其关于双重否定的实际属性
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
和De Morgan's Laws
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 ~~~
报告问题进行更正。