0
计算逻辑运算的规则是什么? (与或异或)两个整数间隔?整数区间的逻辑计算
给定两个时间间隔[A,B]并[c,d] i的要计算[A,B] XOR并[c,d]
我假设的结果是多个范围
我看着在filib ++并阅读WIKI,但发现只是算术操作。支持
谁能教我
计算逻辑运算的规则是什么? (与或异或)两个整数间隔?整数区间的逻辑计算
给定两个时间间隔[A,B]并[c,d] i的要计算[A,B] XOR并[c,d]
我假设的结果是多个范围
我看着在filib ++并阅读WIKI,但发现只是算术操作。支持
谁能教我
您可以找到“按位和”,“按位异或”并在Frama-C最新版本间隔之间“按位或”实现方式,在文件的src/AI/IVAL。毫升。实际上,这些函数对类型为Ival.t
的值进行操作,该值代表一小组整数值,具有同余信息的区间或浮点区间。您只会对Top _, Top _
(对应于具有同余信息的整数间隔)的情况感兴趣。函数将结果计算为Ival.t
,可能是过度逼近的,但其中包含所有值x op y,其中x在第一个区间中,y在第二个区间中。
正如评论所说,pos_max_land
的算法对于精度来说是最优的,但对于整数的位数没有最好的复杂度。在完成写入函数后,我只理解了这一点,对于这个用例,整数的宽度不超过64,所以我没有打算写更快的版本。
src/ai/ival.ml文件在LGPL 2.1下许可。如果你做了一些很酷的事情,我会很乐意听到它。
(* [different_bits min max] returns an overapproximation of the mask
of the bits that can be different for different numbers
in the interval [min]..[max] *)
let different_bits min max =
let x = Int.logxor min max in
next_pred_power_of_two x
(* [pos_max_land min1 max1 min2 max2] computes an upper bound for
[x1 land x2] where [x1] is in [min1]..[max1] and [x2] is in [min2]..[max2].
Precondition : [min1], [max1], [min2], [max2] must all have the
same sign.
Note: the algorithm below is optimal for the problem as stated.
It is possible to compute this optimal solution faster but it does not
seem worth the time necessary to think about it as long as integers
are at most 64-bit. *)
let pos_max_land min1 max1 min2 max2 =
let x1 = different_bits min1 max1 in
let x2 = different_bits min2 max2 in
(* Format.printf "pos_max_land %a %a -> %a | %a %a -> %[email protected]"
Int.pretty min1 Int.pretty max1 Int.pretty x1
Int.pretty min2 Int.pretty max2 Int.pretty x2; *)
let fold_maxs max1 p f acc =
let rec aux p acc =
let p = Int.shift_right p Int.one in
if Int.is_zero p
then f max1 acc
else if Int.is_zero (Int.logand p max1)
then aux p acc
else
let c = Int.logor (Int.sub max1 p) (Int.pred p) in
aux p (f c acc)
in aux p acc
in
let sx1 = Int.succ x1 in
let n1 = fold_maxs max1 sx1 (fun _ y -> succ y) 0 in
let maxs1 = Array.make n1 sx1 in
let _ = fold_maxs max1 sx1 (fun x i -> Array.set maxs1 i x; succ i) 0 in
fold_maxs max2 (Int.succ x2)
(fun max2 acc ->
Array.fold_left
(fun acc max1 -> Int.max (Int.logand max1 max2) acc)
acc
maxs1)
(Int.logand max1 max2)
let bitwise_or v1 v2 =
if is_bottom v1 || is_bottom v2
then bottom
else
match v1, v2 with
Float _, _ | _, Float _ -> top
| Set s1, Set s2 ->
apply2_v Int.logor s1 s2
| Set s, v | v, Set s when Array.length s = 1 && Int.is_zero s.(0) -> v
| Top _, _ | _, Top _ ->
(match min_and_max v1 with
Some mn1, Some mx1 when Int.ge mn1 Int.zero ->
(match min_and_max v2 with
Some mn2, Some mx2 when Int.ge mn2 Int.zero ->
let new_max = next_pred_power_of_two (Int.logor mx1 mx2) in
let new_min = Int.max mn1 mn2 in (* Or can only add bits *)
inject_range (Some new_min) (Some new_max)
| _ -> top)
| _ -> top)
let bitwise_xor v1 v2 =
if is_bottom v1 || is_bottom v2
then bottom
else
match v1, v2 with
| Float _, _ | _, Float _ -> top
| Set s1, Set s2 -> apply2_v Int.logxor s1 s2
| Top _, _ | _, Top _ ->
(match min_and_max v1 with
| Some mn1, Some mx1 when Int.ge mn1 Int.zero ->
(match min_and_max v2 with
| Some mn2, Some mx2 when Int.ge mn2 Int.zero ->
let new_max = next_pred_power_of_two (Int.logor mx1 mx2) in
let new_min = Int.zero in
inject_range (Some new_min) (Some new_max)
| _ -> top)
| _ -> top)
如果范围#1 [1,7]和#2为[3,3]而你或者对他们,你会得到[3,3]和[7,7]没有他们的工会 – BNR 2014-11-04 15:15:54
如果计算[0,0xFFFFFFFF]&[0xFFFFFFFE,0xFFFFFFFE]'作为多个范围的结果,您将获得的范围将占用16 GiB的内存(表示范围为32位最小值和32位最大值,假设一组范围的最紧凑表示)。你确定这是你想要的吗?还是在你没有告诉我们的输入中存在一些限制,使你的用例中的“多范围结果”变得易于处理? – 2014-11-04 15:41:31
你是对的。我写这个例子来证明xor不是简单的联合。在我的情况下,我将选择一个与其他约束不冲突的范围 – BNR 2014-11-04 15:59:35