All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: Eric Blake <eblake@redhat.com>
Cc: Max Reitz <mreitz@redhat.com>, Kevin Wolf <kwolf@redhat.com>,
	qemu-devel@nongnu.org, qemu-block@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v3 2/5] qapi: Add qobject_is_equal()
Date: Wed, 05 Jul 2017 18:11:25 +0200	[thread overview]
Message-ID: <87zicilv82.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <7e9bdf55-c11d-e7cd-d92b-5ccef7e48d3c@redhat.com> (Eric Blake's message of "Wed, 5 Jul 2017 09:15:09 -0500")

Eric Blake <eblake@redhat.com> writes:

> On 07/05/2017 08:48 AM, Max Reitz wrote:
>>>>  /**
>>>> + * qnum_is_equal(): Test whether the two QNums are equal
>>>> + */
>>>> +bool qnum_is_equal(const QObject *x, const QObject *y)
>>>> +{
>>>> +    QNum *num_x = qobject_to_qnum(x);
>>>> +    QNum *num_y = qobject_to_qnum(y);
>>>> +
>>>> +    switch (num_x->kind) {
>>>> +    case QNUM_I64:
>>>> +        switch (num_y->kind) {
>>>> +        case QNUM_I64:
>>>> +            /* Comparison in native int64_t type */
>>>> +            return num_x->u.i64 == num_y->u.i64;
>>>> +        case QNUM_U64:
>>>> +            /* Implicit conversion of x to uin64_t, so we have to
>>>> +             * check its sign before */
>>>> +            return num_x->u.i64 >= 0 && num_x->u.i64 == num_y->u.u64;
>>>> +        case QNUM_DOUBLE:
>>>> +            /* Implicit conversion of x to double; no overflow
>>>> +             * possible */
>>>> +            return num_x->u.i64 == num_y->u.dbl;
>>>
>>> Overflow is impossible, but loss of precision is possible:
>>>
>>>     (double)9007199254740993ull == 9007199254740992.0
>>>
>>> yields true.  Is this what we want?
>> 
>> I'd argue that yes, because the floating point value represents
>> basically all of the values which are "equal" to it.
>
> But the problem is that we CAN represent the fully-precise number as an
> integer, so having multiple distinct integers that compare differently
> against each other, but equal to the same double, is awkward.

Yup.

>> But I don't have a string opinion. I guess the alternative would be to
>> convert the double to an integer instead and check for overflows before?
>
> That's the solution Markus gave, and I'm in favor of the tighter check:
>
[...]
>>> I think there's more than one sane interpretations of "is equal",
>>> including:
>>> 
>>> * The mathematical numbers represented by @x and @y are equal.
>>> 
>>> * @x and @y have the same contents, i.e. same kind and u.
>>> 
>>> * @x and @y are the same object (listed for completeness; we don't need
>>>   a function to compare pointers).
>>> 
>>> Your patch implements yet another one.  Which one do we want, and why?
>>
>> Mine is the first one, except that I think that a floating point value
>> does not represent a single number but just some number in a range.
>>
>>> The second is easier to implement than the first.
>>
>> It seems much less useful, though.

Depends on what for.

Common Lisp has

* eq: same object
* eql: eq, or both numbers with same type and value, or both characters
  that represent the same character
* =: mathematically equal (arguments must be numbers)
* equal: like eql, but it recursively descends into lists (I'm
  simplifying)

Decades of use back the assertion that eq, eql and = are all useful.

>>> If we really want the first, you need to fix the loss of precision bugs.
>>
>> I'm not sure, but I don't mind either, so...

For what it's worth, your v2 had QInt compare not equal to QFloat.
Makes me suspect that eql is good enough for the problem at hand.

>>> I guess the obvious fix is
>>>
>>>     return (double)x == x && x == y;
>> 
>> Yes, that would do, too; and spares me of having to think about how well
>> comparing an arbitrary double to UINT64_MAX actually works. :-)
>
> It basically says that we are unwilling to declare an integer equivalent
> to the double if the double loses precision when trying to store the
> integer.
>
>>> Note that this is what you do for mixed signedness: first check @x is
>>> exactly representable in @y's type, then compare in @y's type.
>>> 
>>> Regardless of which one we pick, the function comment needs to explain.

  reply	other threads:[~2017-07-05 16:11 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-07-03 12:25 [Qemu-devel] [PATCH v3 0/5] block: Don't compare strings in bdrv_reopen_prepare() Max Reitz
2017-07-03 12:25 ` [Qemu-devel] [PATCH v3 1/5] qapi/qnull: Add own header Max Reitz
2017-07-03 12:35   ` Eric Blake
2017-07-03 12:25 ` [Qemu-devel] [PATCH v3 2/5] qapi: Add qobject_is_equal() Max Reitz
2017-07-03 12:44   ` Eric Blake
2017-07-05  7:07   ` Markus Armbruster
2017-07-05 13:48     ` Max Reitz
2017-07-05 14:15       ` Eric Blake
2017-07-05 16:11         ` Markus Armbruster [this message]
2017-07-05 16:05       ` Max Reitz
2017-07-05 16:22         ` Max Reitz
2017-07-05 16:29           ` Eric Blake
2017-07-05 17:00             ` Max Reitz
2017-07-05 17:04               ` Max Reitz
2017-07-05 17:22                 ` Eric Blake
2017-07-05 17:18               ` Eric Blake
2017-07-05 16:30           ` Max Reitz
2017-07-03 12:25 ` [Qemu-devel] [PATCH v3 3/5] block: qobject_is_equal() in bdrv_reopen_prepare() Max Reitz
2017-07-03 12:51   ` Eric Blake
2017-07-03 13:01     ` Max Reitz
2017-07-03 14:29       ` Eric Blake
2017-07-05  7:14   ` Markus Armbruster
2017-07-05 17:50     ` Max Reitz
2017-07-03 12:25 ` [Qemu-devel] [PATCH v3 4/5] iotests: Add test for non-string option reopening Max Reitz
2017-07-03 12:25 ` [Qemu-devel] [PATCH v3 5/5] tests: Add check-qobject for equality tests Max Reitz
2017-07-03 14:15   ` Eric Blake
2017-07-03 16:13     ` Max Reitz
2017-07-05  7:22   ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87zicilv82.fsf@dusky.pond.sub.org \
    --to=armbru@redhat.com \
    --cc=eblake@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.