Thread Links Date Links
Thread Prev Thread Next Thread Index Date Prev Date Next Date Index

Re: P1788.1/M001.01 Missing roundTiesToEven/roundTiesToAway



Simplicity is the goal of the simplified standard.
One aspect of simplicity is a simple and regular API - a user can easyly keep in
his/her mind a set of available operations and their interaction.
Another aspect is a simplicity of implementation.
For me the first aspect has priority over the second aspect.

The main standard 1788 and the simplified standard 1788.1 are related
and, I think, they should be consistent so that user can easy keep them in memory.
The main standard has two parts - the all flavor part and the set-based part.
The simplified standard doesn't mention flavors, but it almost satisfies requirements
to the flavor of the main standard.
There are a few exemptions listed at the end of the simplified standard.

The relation between the standards could be simpler if there were no these exemptions,
though implemention would be a litlle larger. I suggest to remove these exemptions
and include in the standard the missing operations that are required in all flavours of the main standard.

There are currently three exemptions:
- rounding operations;
- cancellative operations;
- syntax of argument of textToInterval(s) constructor.

I will say a few words about rounding operations in this email.
Five rounding operations in the main standard 1788 correspond one-to-one
to 5 rounding directions of IEEE 754/2008:
roundTiesToEven(x)   roundTiesToEven;
roundTiesToAway(x)   roundTiesToAway;
ceil(x)              roundTowardPositive;
floor(x)             roundTowardNegative;
trunc(x)             roundTowardZero .
So it is easy to remember them.
Current draft of the simplified standard omits two of these functions:
roundTiesToEven(x) and roundTiesToAway(x). This seems irregular.
The implementation of this functions is not difficult. 

Below you can look at implementation of roundTiesToEven from
https://java.net/projects/jinterval/sources/svn/content/trunk/jinterval/p1788-launcher-java/src/main/resources/net/java/jinterval/p1788/integerFuns.c?rev=379
I do not consider it difficult.
So I suggest to keep regularity and do not omit roundTiesToEven and roundTiesToAway from the basic standard.

Best Regards,
  -Dima

=============== roundTiesToEven ==============
int roundTiesToEvenBareInfsupB64(BARE_INFSUP_B64 *r, BARE_INFSUP_B64 *x) {
    assert(isValidBareInfsupB64(x));
    int d = COM;

    unsigned long long xi = infbits(x);
    int inf_e = ((int) ((xi & EXP_MASK_B64) >> (PRECISION_B64 - 1))) - EXP_BIAS_B64; // exponent of inf
    if (inf_e <= -1) {
        if ((xi & ~SIGN_MASK_B64) <= 0x3fe0000000000000ULL) // +-0.5
        {
            if ((xi & ~SIGN_MASK_B64) == 0x3fe0000000000000ULL) // +-0.5
            {
                d = DAC;
            }
            xi = SIGN_MASK_B64; // -0
        }
        else
        {
            xi = (xi & SIGN_MASK_B64) | 0x3ff0000000000000ULL; // +-1
        }
    } else if (inf_e < (PRECISION_B64 - 1)) {
        int sh = (PRECISION_B64 - 1) - inf_e; // bits to clear
        xi += (1ULL << (sh - 1)); // add 1/2
        if ((xi & ((1ULL << sh) - 1)) == 0) { // tie
            xi = (xi >> (sh + 1)) << (sh + 1); // round to even
            d = DAC;
        } else {
            xi = (xi >> sh) << sh;
        }
    }

    unsigned long long xs = supbits(x);
    int sup_e = ((int) ((xs & EXP_MASK_B64) >> (PRECISION_B64 - 1))) - EXP_BIAS_B64; // exponent of sup
    if (sup_e <= -1) {
        if ((xs & ~SIGN_MASK_B64) <= 0x3fe0000000000000ULL) // +-0.5
        {
            if ((xs & ~SIGN_MASK_B64) == 0x3fe0000000000000ULL) // +-0.5
            {
                d = DAC;
            }
            xs = 0; // +0
        }
        else
        {
            xs = (xs & SIGN_MASK_B64) | 0x3ff0000000000000ULL; // +-1
        }
    } else if (sup_e < (PRECISION_B64 - 1)) {
        int sh = (PRECISION_B64 - 1) - sup_e; // bits to clear
        xs += (1ULL << (sh - 1)); // add 1/2
        if ((xs & ((1ULL << sh) - 1)) == 0) { // tie
            xs = (xs >> (sh + 1)) << (sh + 1); // round to even
            d = DAC;
        } else {
            xs = (xs >> sh) << sh;
        }
    }

    if (xi != xs && (xi != SIGN_MASK_B64 || xs != 0)) {
        if (xs == NEG_INFINITY_B64) {
            setEmptyBareInfsupB64(r);
            return TRV;
        }
        d = DEF;
    }
    setbits(r, xi, xs);
    return d;
}
===============