limits

2 views
Skip to first unread message

Matthieu Dubuget

unread,
Mar 16, 2010, 1:18:12 PM3/16/10
to bits...@googlegroups.com
Hello,

I'm trying to understand some bitstring functions.

Is it ok that we can write:

# let b = BITSTRING { min_int : 31 : unsigned } ;;
val b : Bitstring.bitstring = ("\128\000\000\000", 0, 31)
# Bitstring.hexdump_bitstring stdout b;;
00000000 80 00 00 00
|.... |
- : unit = ()


I would have allowed only values between 0 and max_int?

I'm asking this, because I'm currently adding _signed functions to
bitstring,
and restricted allowed values like this :

let range_signed v bits =
if
bits = 31
then
v >= min_int && v <= max_int
else
let succ_max_val = 1 lsl pred bits in
v < succ_max_val &&
v > (- succ_max_val - 1)


But I'm not sure it is the same logic as the range_unsigned function?

Salutations

Matthieu

Richard Jones

unread,
Mar 16, 2010, 2:49:19 PM3/16/10
to bits...@googlegroups.com
On Tue, Mar 16, 2010 at 06:18:12PM +0100, Matthieu Dubuget wrote:
> I'm trying to understand some bitstring functions.
>
> Is it ok that we can write:
>
> # let b = BITSTRING { min_int : 31 : unsigned } ;;
> val b : Bitstring.bitstring = ("\128\000\000\000", 0, 31)
> # Bitstring.hexdump_bitstring stdout b;;
> 00000000 80 00 00 00
> |.... |
> - : unit = ()
>
> I would have allowed only values between 0 and max_int?

This is a tricky point. If we only allowed unsigned values there
(ie. >= 0) then you could not express the full 31 bit range of values.
This is because the range of unsigned values expressible in an OCaml
int [on a 32 bit platform] is 0..max_int which is 0x3fff_ffff. That's
30 bits, not 31 bits.

So if we restricted values to be positive, then we'd need to change
the type of the value to be an int64, and that would break the
assumptions in this table:

http://people.redhat.com/~rjones/bitstring/html/Bitstring.html#integertypes

Users would have to worry about whether the type was signed or
unsigned, and the corner cases around the 30/31/32 bit point in that
table would become really nasty.

So I think it's better to allow a signed value there, which means the
code above is *not* a bug.

Do you agree?

> I'm asking this, because I'm currently adding _signed functions to
> bitstring,
> and restricted allowed values like this :
>
> let range_signed v bits =
> if
> bits = 31
> then
> v >= min_int && v <= max_int
> else
> let succ_max_val = 1 lsl pred bits in
> v < succ_max_val &&
> v > (- succ_max_val - 1)
>
> But I'm not sure it is the same logic as the range_unsigned function?

I think you should just restrict based on the number of bits, so
let range_signed = range_unsigned.

Rich.

--
Richard Jones
Red Hat

Matthieu Dubuget

unread,
Mar 16, 2010, 3:59:52 PM3/16/10
to bits...@googlegroups.com
-------- Original Message --------
Subject: Re: [bitstring] limits
From: Richard Jones <ri...@annexia.org>
To: bits...@googlegroups.com
Date: 16/03/2010 19:49
> …
>
> Users would have to worry about whether the type was signed or
> unsigned, and the corner cases around the 30/31/32 bit point in that
> table would become really nasty.
>

Yes. Simpler is better.

> …
>
> Do you agree?
>

Of course! I just asked to be sure.

>> I'm asking this, because I'm currently adding _signed functions to
>> bitstring,
>> and restricted allowed values like this :
>>
>> let range_signed v bits =
>> if
>> bits = 31
>> then

>> v>= min_int&& v<= max_int


>> else
>> let succ_max_val = 1 lsl pred bits in
>> v< succ_max_val&&
>> v> (- succ_max_val - 1)
>>
>> But I'm not sure it is the same logic as the range_unsigned function?
>>
> I think you should just restrict based on the number of bits, so
> let range_signed = range_unsigned.
>

OK. I will stick to the original version, and add some unit tests to
validate my code.

Thanks for this library, that made my code more readable.

Matt

Matthieu Dubuget

unread,
Mar 17, 2010, 7:04:47 AM3/17/10
to bits...@googlegroups.com
-------- Original Message --------
Subject: Re: [bitstring] limits
From: Richard Jones <ri...@annexia.org>
To: bits...@googlegroups.com
Date: 16/03/2010 19:49
> I think you should just restrict based on the number of bits, so
> let range_signed = range_unsigned.
>

Hello again,

I think this is not ok for signed integers, because negative integers
are not allowed by construct_char_unsigned or by range_unsigned (except
if bits = 31).

We do need a range_signed function.

Consider 3 bits integers (this is only an example; I'm speaking about
both construct_char_signed and construct_int_*_signed)

bin u s
000 0 0
001 1 1
010 2 2
011 3 3
100 4 -4
101 5 -3
110 6 -2
111 7 -1

BITSTRING { n : 3 } will work for n in [0..7]. OK.

But what about BITSTRING {n : 3 : signed }?

We can allow either:
* n in [-4..3]
* or n in [-4..7]

What do you think is better?

I implemented the second solution (see later) because it allows to do:

BITSTRING {7:3:signed}, which bitmatched again { n:3:signed } would
return -1 and { n:3:unsigned } would return 7.

Salutations

Matt


Reply all
Reply to author
Forward
0 new messages