Am 01.12.2010 23:33, schrieb Joe Darcy:
Rémi Forax wrote:

I just wonder why twoToTheDoubleScaleUp and twoToTheDoubleScaleDown in FpUtils
aren't real constants (static final).

Just an oversight; they are logically constants -- the next time I edit this 
class, I'll fix that.

IMHO those constants are superfluous, as they are only used once.
Additionally, scale_factor only needs to range-adjusted in [-MAX_SCALE, 
MAX_SCALE]
So we can code much more simple:

    public static double scalb(double d, int scale_factor) {
        // ...
        final int MAX_SCALE = DoubleConsts.MAX_EXPONENT + 
-DoubleConsts.MIN_EXPONENT +
                              DoubleConsts.SIGNIFICAND_WIDTH + 1;

        // Make sure scaling factor is in a reasonable range

        scale_factor = Math.min(Math.max(scale_factor, -MAX_SCALE), MAX_SCALE);
        int scale_delta= 512;
        double exp_delta = powerOfTwoD(scale_delta);
        if(scale_factor < 0)
            exp_delta = powerOfTwoD(scale_delta= -scale_delta);

        // Calculate (scale_factor % +/-512), 512 = 2^9, using
        // technique from "Hacker's Delight" section 10-2.
        final int t = (scale_factor >> 9-1) >>> 32 - 9;
        final int exp_adjust = ((scale_factor + t) & (512 -1)) - t;

        for(d*=powerOfTwoD(exp_adjust), scale_factor-=exp_adjust;
                scale_factor!=0; scale_factor-=scale_delta)
            d *= exp_delta;
        return d;
    }

And even more simpler, if we trust the optimizer:

    public static double scalb(double d, int scale_factor) {
        // ...
        final int MAX_SCALE = DoubleConsts.MAX_EXPONENT + 
-DoubleConsts.MIN_EXPONENT +
                              DoubleConsts.SIGNIFICAND_WIDTH + 1;

        // Make sure scaling factor is in a reasonable range

        scale_factor = Math.min(Math.max(scale_factor, -MAX_SCALE), MAX_SCALE);
        final int scale_delta = scale_factor < 0 ? -512 : 512;
        final double exp_delta = powerOfTwoD(scale_delta);

        // Calculate (scale_factor % +/-512), 512 = 2^9, using
        // technique from "Hacker's Delight" section 10-2.
        final int t = (scale_factor >> 9-1) >>> 32 - 9;
        final int exp_adjust = ((scale_factor + t) & (512 -1)) - t;

        for(d*=powerOfTwoD(exp_adjust), scale_factor-=exp_adjust;
                scale_factor!=0; scale_factor-=scale_delta)
            d *= exp_delta;
        return d;
    }


- Ulf

Reply via email to