All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: Max Reitz <mreitz@redhat.com>
Cc: qemu-block@nongnu.org, Kevin Wolf <kwolf@redhat.com>,
	qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH v3 2/5] qapi: Add qobject_is_equal()
Date: Wed, 05 Jul 2017 09:07:18 +0200	[thread overview]
Message-ID: <87r2xve509.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <20170703122505.32017-3-mreitz@redhat.com> (Max Reitz's message of "Mon, 3 Jul 2017 14:25:02 +0200")

Max Reitz <mreitz@redhat.com> writes:

> This generic function (along with its implementations for different
> types) determines whether two QObjects are equal.
>
> Signed-off-by: Max Reitz <mreitz@redhat.com>
[...]
> diff --git a/qobject/qnum.c b/qobject/qnum.c
> index 476e81c..784d061 100644
> --- a/qobject/qnum.c
> +++ b/qobject/qnum.c
> @@ -213,6 +213,59 @@ QNum *qobject_to_qnum(const QObject *obj)
>  }
>  
>  /**
> + * 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?

> +        }
> +        abort();
> +    case QNUM_U64:
> +        switch (num_y->kind) {
> +        case QNUM_I64:
> +            return qnum_is_equal(y, x);
> +        case QNUM_U64:
> +            /* Comparison in native uint64_t type */
> +            return num_x->u.u64 == num_y->u.u64;
> +        case QNUM_DOUBLE:
> +            /* Implicit conversion of x to double; no overflow
> +             * possible */
> +            return num_x->u.u64 == num_y->u.dbl;

Similar loss of precision.

> +        }
> +        abort();
> +    case QNUM_DOUBLE:
> +        switch (num_y->kind) {
> +        case QNUM_I64:
> +            return qnum_is_equal(y, x);
> +        case QNUM_U64:
> +            return qnum_is_equal(y, x);
> +        case QNUM_DOUBLE:
> +            /* Comparison in native double type */
> +            return num_x->u.dbl == num_y->u.dbl;
> +        }
> +        abort();
> +    }
> +
> +    abort();
> +}

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?

The second is easier to implement than the first.

If we really want the first, you need to fix the loss of precision bugs.
I guess the obvious fix is

    return (double)x == x && x == y;

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.

> +
> +/**
>   * qnum_destroy_obj(): Free all memory allocated by a
>   * QNum object
>   */
[...]

Remainder of the patch looks good to me.

  parent reply	other threads:[~2017-07-05  7:07 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 [this message]
2017-07-05 13:48     ` Max Reitz
2017-07-05 14:15       ` Eric Blake
2017-07-05 16:11         ` Markus Armbruster
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=87r2xve509.fsf@dusky.pond.sub.org \
    --to=armbru@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.