// $Id: BitUtils.java,v 1.1 2004/07/29 03:45:31 Dave Exp $
/*
* BitUtils.java
* Copyright (C) 2003, 2004 David Clausen
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
package com.jopdesign.sys;
/**
* Helper class providing bit-shift functions which are used internally by
* the <code>Float</code> and <code>Double</code> classes.
*/
final class BitUtils {
private BitUtils() {
}
/**
* Returns the number of contiguous 0 bits starting with the most significant
* bit of x.
*/
static int countLeadingZeros(int x) {
if (x <= 0) {
if (x == 0) {
return 32;
}
return 0;
}
int count = 0;
if ((x & 0xffff0000) == 0) {
x <<= 16;
count = 16;
}
if ((x & 0xff000000) == 0) {
x <<= 8;
count += 8;
}
while (x > 0) { // @WCA loop<=8
count++;
x <<= 1;
}
return count;
}
/**
* Returns the number of contiguous 0 bits starting with the most significant
* bit of x.
*/
static int countLeadingZeros(long x) {
int c = countLeadingZeros((int) (x >> 32));
if (c == 32) {
return countLeadingZeros((int) x) + 32;
}
return c;
}
/**
* Right-shift x by count bits, and if any of the shifted-off bits are 1,
* set the least significant bit of the return value to 1.
*/
static int stickyRightShift(int x, int count) {
if (count >= 32) {
return ((x == 0) ? 0 : 1);
} else if ((x << (32 - count)) == 0) {
return x >>> count;
} else {
return (x >>> count) | 1;
}
}
/**
* Right-shift x by count bits, and if any of the shifted-off bits are 1,
* set the least significant bit of the return value to 1.
*/
static long stickyRightShift(long x, int count) {
if (count >= 64) {
return ((x == 0) ? 0 : 1);
} else if ((x << (64 - count)) == 0) {
return x >>> count;
} else {
return (x >>> count) | 1;
}
}
/**
* Right-shift x by count bits, and round the result using half-even rounding.
*/
static int roundingRightShift(int x, int count) {
int remainder;
if (count > 32) {
return 0;
} else if (count == 32) {
remainder = x;
x = 0;
} else {
remainder = x << (32 - count);
x >>>= count;
}
if ((remainder < 0) && ((remainder != 0x80000000) || ((x & 1) == 1))) {
return x + 1;
}
return x;
}
/**
* Right-shift x by count bits, and round the result using half-even rounding.
*/
static long roundingRightShift(long x, int count) {
long remainder;
if (count > 64) {
return 0;
} else if (count == 64) {
remainder = x;
x = 0;
} else {
remainder = x << (64 - count);
x >>>= count;
}
if ((remainder < 0)
&& ((remainder != 0x8000000000000000L) || ((x & 1) == 1))) {
return x + 1;
}
return x;
}
}