[PATCH] Implement floordiv operator for gdb.Value

Jonathan Wakely jwakely@redhat.com
Tue Sep 20 17:11:00 GMT 2016


On 20/09/16 17:57 +0100, Pedro Alves wrote:
>On 09/20/2016 05:35 PM, Jonathan Wakely wrote:
>> On 20/09/16 16:33 +0100, Pedro Alves wrote:
>>> Hi there,
>>>
>>> Thanks!
>>>
>>> On 09/20/2016 02:26 PM, Jonathan Wakely wrote:
>>>> This is my attempt to implement the // operator on gdb.Value objects.
>>>> There is already BINOP_INTDIV which works fine for integral types, but
>>>> for floats I use BINOP_DIV and then call floor() on the result. This
>>>> doesn't support decimal floats though.
>>>>
>>>> Is this a reasonable solution? Is the test sufficient?
>>>>
>>>
>>> See below.
>>>
>>>> @@ -1142,7 +1160,15 @@ valpy_binop_throw (enum valpy_opcode opcode,
>>>> PyObject *self, PyObject *other)
>>>>      }
>>>>
>>>>    if (res_val)
>>>> -    result = value_to_value_object (res_val);
>>>> +    {
>>>> +      if (floor_it)
>>>> +        {
>>>> +          double d = value_as_double (res_val);
>>>
>>> Should be s/double/DOUBLEST, I suppose?
>>
>> OK - if I do that then floor(d) will convert it back to double,
>> unless you #include <cmath> and using std::floor, so that the overload
>> for long double is visible (in C++ <math.h> names like floor are
>> overloaded so you don't need to use floorf/floor/floorl according to
>> the type).
>
>OK.  I remember reading your blog about this mess a while ago.
>
>If easy to do, sounds like we should just do it.  OOC, would calling
>std::floor directly instead of using "using" work just as well?

Yes, and that's exactly what I did locally a few minutes ago. Calling
std::floor explicitly probably makes it more obvious that it relies on
the C++ overloads to preserve the right type.

>(This kind of raises the question of which float type / format / representation
>to use for arithmetic here -- host's or target's.  gdb currently always
>uses host's, but that's a much larger issue that we can just
>continue to ignore.)

I'm happy to ignore it :-)

>>> Is the "two double values" test returning an integer somehow?
>>>
>>> I ask because IIUC, regardless of Python version, a floor-divide
>>> involving a float should result in a float, while a floor-divide of
>>> integers should result in an integer.  And that's what the patch looks
>>> like should end up with.  So I was expecting to see "0.0" in
>>> the "two double values" case:
>>>
>>> (gdb) python print (5.0//6.0)
>>> 0.0
>>> (gdb) python print (5//6)
>>> 0
>>
>> This seems to be an existing property of gdb.Value, as even using the
>> normal division operator (and without my patch) I see floats printed
>> without a decimal part when they are an integer value:
>>
>> (gdb) python print (gdb.Value(5.0)/5.0)
>> 1
>> (gdb) python print (5.0/5.0)
>> 1.0
>
>Curious.  Off hand looks like a bug to me.  But since it's orthogonal
>to your patch, let's leave it.
>
>>> I think it'd be good to test with negative numbers too, to make
>>> sure that we round (and keep rounding) toward the same
>>> direction Python rounds:
>>>
>>> (gdb) python print (8.0//-3)
>>> -3.0
>>> (gdb) python print (8//-3)
>>> -3
>>> (gdb) print 8/-3
>>> $1 = -2
>>
>> Good point, I'll do that.

Definitely worth testing because my patch gives the wrong result:

(gdb) python print(  gdb.Value(8) // gdb.Value(-3) )
-2

This is because I'm using the same BINOP_DIV operation as GDB's 8/-3
uses, but Python's // should round to -inf. I'll fix that.



More information about the Gdb-patches mailing list