org.mentalog.util.StringUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of menta-log Show documentation
Show all versions of menta-log Show documentation
A log library that embraces the kiss principle.
package org.mentalog.util;
import java.util.Arrays;
class StringUtils {
private static final long MAX_VALUE_DIVIDE_5 = Long.MAX_VALUE / 5;
private static final String MIN_VALUE_TEXT = "" + Long.MIN_VALUE;
public final static boolean equal(CharSequence sb1, CharSequence sb2) {
if (sb1.length() == sb2.length()) {
for (int i = 0; i < sb1.length(); i++) {
if (sb1.charAt(i) != sb2.charAt(i)) {
return false;
}
}
return true;
}
return false;
}
public final static boolean equal(CharSequence sb, String s) {
if (sb.length() == s.length()) {
for (int i = 0; i < s.length(); i++) {
if (sb.charAt(i) != s.charAt(i)) {
return false;
}
}
return true;
}
return false;
}
public final static int indexOf(CharSequence sb, int start, char c) {
for (int i = start; i < sb.length(); i++) {
if (sb.charAt(i) == c) {
return i;
}
}
return -1;
}
public final static int indexOf(CharSequence sb, char c) {
return indexOf(sb, 0, c);
}
public final static void copy(CharSequence sb, byte[] dst) {
if (sb.length() > dst.length) {
throw new RuntimeException("Byte array is not big enough!");
}
for (int i = 0; i < sb.length(); i++) {
dst[i] = (byte) sb.charAt(i);
}
}
public final static void copy(char[] array, StringBuilder sb) {
for (int i = 0; i < array.length; i++) {
sb.append(array[i]);
}
}
public final static void copy(CharSequence sb1, int start, int end, StringBuilder sb2) {
int len = end - start;
for (int i = 0; i < len; i++) {
sb2.append(sb1.charAt(start + i));
}
}
public final static void copy(CharSequence sb1, StringBuilder sb2) {
copy(sb1, 0, sb1.length(), sb2);
}
public final static void copy(CharSequence sb1, int end, StringBuilder sb2) {
copy(sb1, 0, end, sb2);
}
public final static boolean isBlank(CharSequence sb, int start, int end) {
int len = end - start;
for (int i = 0; i < len; i++) {
if (sb.charAt(start + i) != ' ') {
return false;
}
}
return true;
}
public final static boolean isBlank(CharSequence sb, int end) {
return isBlank(sb, 0, end);
}
public final static boolean isBlank(CharSequence sb) {
return isBlank(sb, 0, sb.length());
}
public final static void trim(StringBuilder sb) {
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(0))) {
sb.deleteCharAt(0);
}
while (sb.length() > 0 && Character.isWhitespace(sb.charAt(sb.length() - 1))) {
sb.deleteCharAt(sb.length() - 1);
}
}
static final long[] TENS = new long[19];
static {
TENS[0] = 1;
for (int i = 1; i < TENS.length; i++) {
TENS[i] = TENS[i - 1] * 10;
}
}
private static long power10(long l) {
int idx = Arrays.binarySearch(TENS, l);
return idx >= 0 ? TENS[idx] : TENS[~idx - 1];
}
private static void appendLong0(StringBuilder sb, long num) {
// find the number of digits
long power10 = power10(num);
// starting from the end, write each digit
while (power10 > 0) {
// write the lowest digit.
sb.append((char) (num / power10 % 10 + '0'));
// remove that digit.
power10 /= 10;
}
}
private static double asDouble(long value, int exp, boolean negative, int decimalPlaces) {
if (decimalPlaces > 0 && value < Long.MAX_VALUE / 2) {
if (value < Long.MAX_VALUE / (1L << 32)) {
exp -= 32;
value <<= 32;
}
if (value < Long.MAX_VALUE / (1L << 16)) {
exp -= 16;
value <<= 16;
}
if (value < Long.MAX_VALUE / (1L << 8)) {
exp -= 8;
value <<= 8;
}
if (value < Long.MAX_VALUE / (1L << 4)) {
exp -= 4;
value <<= 4;
}
if (value < Long.MAX_VALUE / (1L << 2)) {
exp -= 2;
value <<= 2;
}
if (value < Long.MAX_VALUE / (1L << 1)) {
exp -= 1;
value <<= 1;
}
}
for (; decimalPlaces > 0; decimalPlaces--) {
exp--;
long mod = value % 5;
value /= 5;
int modDiv = 1;
if (value < Long.MAX_VALUE / (1L << 4)) {
exp -= 4;
value <<= 4;
modDiv <<= 4;
}
if (value < Long.MAX_VALUE / (1L << 2)) {
exp -= 2;
value <<= 2;
modDiv <<= 2;
}
if (value < Long.MAX_VALUE / (1L << 1)) {
exp -= 1;
value <<= 1;
modDiv <<= 1;
}
value += modDiv * mod / 5;
}
final double d = Math.scalb((double) value, exp);
return negative ? -d : d;
}
public final static StringBuilder append(StringBuilder sb, double d) {
// Apache License 2.0 => Code by Peter Lawrey
// https://github.com/peter-lawrey/Java-Chronicle/blob/master/src/main/java/vanilla/java/chronicle/impl/AbstractExcerpt.java
long val = Double.doubleToRawLongBits(d);
int sign = (int) (val >>> 63);
int exp = (int) ((val >>> 52) & 2047);
long mantissa = val & ((1L << 52) - 1);
if (sign != 0) {
sb.append('-');
}
if (exp == 0 && mantissa == 0) {
sb.append('0');
return sb;
} else if (exp == 2047) {
if (mantissa == 0) {
sb.append("Infinity");
} else {
sb.append("NaN");
}
return sb;
} else if (exp > 0) {
mantissa += 1L << 52;
}
final int shift = (1023 + 52) - exp;
if (shift > 0) {
// integer and faction
if (shift < 53) {
long intValue = mantissa >> shift;
appendLong0(sb, intValue);
mantissa -= intValue << shift;
if (mantissa > 0) {
sb.append('.');
mantissa <<= 1;
mantissa++;
int precision = shift + 1;
long error = 1;
long value = intValue;
int decimalPlaces = 0;
while (mantissa > error) {
// times 5*2 = 10
mantissa *= 5;
error *= 5;
precision--;
long num = (mantissa >> precision);
value = value * 10 + num;
sb.append((char) ('0' + num));
mantissa -= num << precision;
final double parsedValue = asDouble(value, 0, sign != 0, ++decimalPlaces);
if (parsedValue == d) {
break;
}
}
}
return sb;
} else {
// faction.
sb.append('0');
sb.append('.');
mantissa <<= 6;
mantissa += (1 << 5);
int precision = shift + 6;
long error = (1 << 5);
long value = 0;
int decimalPlaces = 0;
while (mantissa > error) {
while (mantissa > MAX_VALUE_DIVIDE_5) {
mantissa >>>= 1;
error = (error + 1) >>> 1;
precision--;
}
// times 5*2 = 10
mantissa *= 5;
error *= 5;
precision--;
if (precision >= 64) {
decimalPlaces++;
sb.append('0');
continue;
}
long num = (mantissa >>> precision);
value = value * 10 + num;
final char c = (char) ('0' + num);
assert !(c < '0' || c > '9');
sb.append(c);
mantissa -= num << precision;
final double parsedValue = asDouble(value, 0, sign != 0, ++decimalPlaces);
if (parsedValue == d) {
break;
}
}
return sb;
}
}
// large number
mantissa <<= 10;
int precision = -10 - shift;
int digits = 0;
while ((precision > 53 || mantissa > Long.MAX_VALUE >> precision) && precision > 0) {
digits++;
precision--;
long mod = mantissa % 5;
mantissa /= 5;
int modDiv = 1;
while (mantissa < MAX_VALUE_DIVIDE_5 && precision > 1) {
precision -= 1;
mantissa <<= 1;
modDiv <<= 1;
}
mantissa += modDiv * mod / 5;
}
long val2 = precision > 0 ? mantissa << precision : mantissa >>> -precision;
appendLong0(sb, val2);
for (int i = 0; i < digits; i++) {
sb.append('0');
}
return sb;
}
public final static StringBuilder append(StringBuilder sb, long num) {
// Apache License 2.0 => Code by Peter Lawrey
// https://github.com/peter-lawrey/Java-Chronicle/blob/master/src/main/java/vanilla/java/chronicle/impl/AbstractExcerpt.java
if (num < 0) {
if (num == Long.MIN_VALUE) {
sb.append(MIN_VALUE_TEXT);
return sb;
}
sb.append('-');
num = -num;
}
if (num == 0) {
sb.append('0');
} else {
appendLong0(sb, num);
}
return sb;
}
public static void main(String[] args) {
double d = 234.34232022;
StringBuilder sb = new StringBuilder(32);
append(sb, d);
System.out.println(sb);
sb.setLength(0);
append(sb, 123456789L);
System.out.println(sb);
}
}