All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.mentalog.util.StringUtils Maven / Gradle / Ivy

There is a newer version: 2.1.2
Show newest version
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);
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy