/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library 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 Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.util;
/**
* @author epr
*/
public class NumberUtils {
/**
* Convert a float to a string with a given maximum number of fraction digits.
*
* @param value
* @param maxFractionLength
* @return The string
*/
public static String toString(float value, int maxFractionLength) {
String s = Float.toString(value);
final int idx = s.indexOf('.');
if (idx >= 0) {
final int len = Math.min(s.length(), idx + maxFractionLength + 1);
return s.substring(0, len);
} else {
return s;
}
}
/**
* Converts a byte to an unsigned value.
*/
public static int toUnsigned(final byte b) {
return b & 0xFF;
}
/**
* Converts a short to an unsigned value.
*/
public static int toUnsigned(final short s) {
return s & 0xFFFF;
}
/**
* Converts an int to an unsigned value.
*/
public static long toUnsigned(final int i) {
return i & 0xFFFFFFFFL;
}
/**
* Gets the hexadecimal representation of the given number. The result is
* prefixed with '0' until the given length is reached.
*
* @param number
* @param length
* @return String
*/
public static String hex(int number, int length) {
StringBuilder buf = new StringBuilder(length);
int2HexString(buf, number);
return prefixZero(buf, length);
}
/**
* Gets the hexadecimal representation of the given number that is
* 8 digits long.
*
* @param number
* @return String
*/
public static String hex(int number) {
return hex(number, 8);
}
/**
* Gets the hexadecimal representation of the given number. The result is
* prefixed with '0' until the given length is reached.
*
* @param number
* @param length
* @return String
*/
public static String hex(long number, int length) {
StringBuilder buf = new StringBuilder(length);
long2HexString(buf, number);
return prefixZero(buf, length);
}
/**
* Gets the hexadecimal representation of the given number that is
* 16 digits long.
*
* @param number
* @return String
*/
public static String hex(long number) {
return hex(number, 16);
}
/**
* Convert a byte array to a string of hex-numbers adding a space between bytes.
*
* @param data the byte array to convert
* @param offset start offset
* @param length the number of bytes to convert
* @return String the result
*/
public static String hex(byte[] data, int offset, int length) {
final StringBuilder buf = new StringBuilder(length * 3);
for (int i = 0; i < length; i++) {
if (i > 0) {
if ((i % 16) == 0) {
buf.append('\n');
} else {
buf.append(' ');
}
}
buf.append(hex(data[offset + i] & 0xFF, 2));
}
return buf.toString();
}
/**
* Convert a byte array to a string of hex-numbers without spaces.
*
* @param data the byte array to convert
* @param offset start offset
* @param length the number of bytes to convert
* @return String the result
*/
public static String hexCompact(byte[] data, int offset, int length) {
final StringBuilder buf = new StringBuilder(length * 2);
for (int i = 0; i < length; i++) {
if (i > 0) {
if ((i % 16) == 0) {
buf.append('\n');
}
}
buf.append(hex(data[offset + i] & 0xFF, 2));
}
return buf.toString();
}
/**
* Convert a int array to a string of hex-numbers
*
* @param data
* @param offset
* @param length
* @param hexLength
* @return String
*/
public static String hex(int[] data, int offset, int length, int hexLength) {
final StringBuilder buf = new StringBuilder(length * (hexLength + 1));
for (int i = 0; i < length; i++) {
if (i > 0) {
if ((i % 16) == 0) {
buf.append('\n');
} else {
buf.append(' ');
}
}
buf.append(hex(data[offset + i], hexLength));
}
return buf.toString();
}
/**
* Convert a char array to a string of hex-numbers
*
* @param data
* @param offset
* @param length
* @return String
*/
public static String hex(char[] data, int offset, int length) {
final StringBuilder buf = new StringBuilder(length * 3);
for (int i = 0; i < length; i++) {
if (i > 0) {
if ((i % 16) == 0) {
buf.append('\n');
} else {
buf.append(' ');
}
}
buf.append(hex(data[offset + i], 2));
}
return buf.toString();
}
/**
* Convert a byte array to a string of hex-numbers
*
* @param data
* @return String
*/
public static String hex(byte[] data) {
return hex(data, 0, data.length);
}
/**
* Convert an int array to a string of hex-numbers
*
* @param data
* @param hexLength
* @return String
*/
public static String hex(int[] data, int hexLength) {
return hex(data, 0, data.length, hexLength);
}
private static String prefixZero(StringBuilder v, int length) {
if (v.length() > length) {
// truncate leading chars
return v.substring(v.length() - length);
} else {
// insert leading '0's
while (v.length() < length) {
v.insert(0, '0');
}
return v.toString();
}
}
/**
* Convert the given value to a size string like 64K
*
* @param v the size to convert
* @return the text for of the size
* @deprecated use toDecimalByte() or toBinaryByte() instead
*/
public static String size(long v) {
for (SizeUnit unit : SizeUnit.values()) {
if ((v < 1024) && (v >= 0)) {
return String.valueOf(v) + unit.getUnit();
}
v = v >>> 10;
}
return String.valueOf(v >>> 10) + SizeUnit.MAX.getUnit();
}
/**
* Convert the given value to a size string like 64K
*
* @param v the size to convert
* @return the text for of the size
*/
public static String toDecimalByte(long v) {
return toDecimalByte(v, 2);
}
/**
* Convert the given value to a size string like 64K
*
* @param v the size to convert
* @param nbDecimals number of significant figures to display after dot. use Integer.MAX_VALUE for all
* @return the text for of the size
*/
public static String toDecimalByte(long v, int nbDecimals) {
return DecimalScaleFactor.apply(v, nbDecimals) + 'B';
}
/**
* Convert the given value to a size string like 64K
*
* @param v the size to convert
* @param nbDecimals number of significant figures to display after dot. use Integer.MAX_VALUE for all
* @return the text for of the size
*/
public static String toBinaryByte(long v, int nbDecimals) {
return BinaryScaleFactor.apply(v, nbDecimals) + 'B';
}
/**
* Convert the given value to a size string like 64K
*
* @param v the size to convert
* @return the text for of the size
*/
public static String toBinaryByte(long v) {
return toBinaryByte(v, 2);
}
/**
* @param size a number eventually followed by a multiplier (K: Kilobytes, M: Megabytes, G:Gigabytes, ...)
* @return the numeric value of the size
*/
public static long getSize(String size) {
if ((size == null) || size.trim().isEmpty())
return 0;
size = size.trim();
long multiplier = SizeUnit.MIN.getMultiplier();
SizeUnit sizeUnit = getSizeUnit(size);
if (sizeUnit != null) {
multiplier = sizeUnit.getMultiplier();
size = size.substring(0, size.length() - sizeUnit.getUnit().length());
}
return Long.parseLong(size) * multiplier;
}
public static SizeUnit getSizeUnit(String size) {
if ((size == null) || size.trim().isEmpty())
return null;
size = size.trim();
for (SizeUnit unit : SizeUnit.values()) {
String unitStr = unit.getUnit();
if (size.endsWith(unitStr)) {
return unit;
}
}
return null;
}
/**
* This method avoids the use on Integer.toHexString, since this class may be used
* during the boot-phase when the Integer class in not yet initialized.
*
* @param buf
* @param value
*/
private static void int2HexString(StringBuilder buf, int value) {
int rem = value & 0x0F;
int q = value >>> 4;
if (q != 0) {
int2HexString(buf, q);
}
if (rem < 10) {
buf.append((char) ('0' + rem));
} else {
buf.append((char) ('A' + rem - 10));
}
}
/**
* This method avoids the use on Long.toHexString, since this class may be used
* during the boot-phase when the Long class in not yet initialized.
*
* @param buf
* @param value
*/
private static void long2HexString(StringBuilder buf, long value) {
// long rem = value & 0x0F;
int rem = (int) (value & 0x0FL);
long q = value >>> 4;
if (q != 0) {
long2HexString(buf, q);
}
if (rem < 10) {
buf.append((char) ('0' + rem));
} else {
buf.append((char) ('A' + rem - 10));
}
}
}