|
|
@@ -7,15 +7,15 @@
|
|
|
package net.ranides.assira.math;
|
|
|
|
|
|
/**
|
|
|
- *
|
|
|
+ *
|
|
|
* @author ranides
|
|
|
*/
|
|
|
public final class MathUtils {
|
|
|
-
|
|
|
+
|
|
|
private MathUtils() {
|
|
|
// utility class
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Sprawdza, czy podana wartość mieści się w określonym zakresie (domkniętym).
|
|
|
* @param value
|
|
|
@@ -26,7 +26,7 @@ public final class MathUtils {
|
|
|
public static boolean inRange(int value, int min, int max) {
|
|
|
return value >= min && value <= max;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Sprawdza, czy podana wartość mieści się w określonym zakresie (domkniętym).
|
|
|
* @param value
|
|
|
@@ -37,7 +37,7 @@ public final class MathUtils {
|
|
|
public static boolean inRange(byte value, byte min, byte max) {
|
|
|
return value >= min && value <= max;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Sprawdza, czy podana wartość mieści się w określonym zakresie (domkniętym).
|
|
|
* @param value
|
|
|
@@ -48,9 +48,9 @@ public final class MathUtils {
|
|
|
public static boolean inRange(long value, long min, long max) {
|
|
|
return value >= min && value <= max;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * Przycina podaną wartość do podanego zakresu. To znaczy, że jeśli
|
|
|
+ * Przycina podaną wartość do podanego zakresu. To znaczy, że jeśli
|
|
|
* {@code value < min}, to zwraca {@code min}, jeśli
|
|
|
* {@code value > max}, to zwraca {@code max}, jeśli wartość mieści się w
|
|
|
* podanym zakresie, to jest zwracana bez zmian.
|
|
|
@@ -63,9 +63,9 @@ public final class MathUtils {
|
|
|
assert min <= max;
|
|
|
return value < min ? min : value > max ? max : value;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * Przycina podaną wartość do podanego zakresu. To znaczy, że jeśli
|
|
|
+ * Przycina podaną wartość do podanego zakresu. To znaczy, że jeśli
|
|
|
* {@code value < min}, to zwraca {@code min}, jeśli
|
|
|
* {@code value > max}, to zwraca {@code max}, jeśli wartość mieści się w
|
|
|
* podanym zakresie, to jest zwracana bez zmian.
|
|
|
@@ -78,9 +78,9 @@ public final class MathUtils {
|
|
|
assert min <= max;
|
|
|
return value < min ? min : value > max ? max : value;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * Przycina podaną wartość do podanego zakresu. To znaczy, że jeśli
|
|
|
+ * Przycina podaną wartość do podanego zakresu. To znaczy, że jeśli
|
|
|
* {@code value < min}, to zwraca {@code min}, jeśli
|
|
|
* {@code value > max}, to zwraca {@code max}, jeśli wartość mieści się w
|
|
|
* podanym zakresie, to jest zwracana bez zmian.
|
|
|
@@ -93,12 +93,12 @@ public final class MathUtils {
|
|
|
assert min <= max;
|
|
|
return value < min ? min : value > max ? max : value;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * Przycina podaną wartość do podanego zakresu i zaokrągla do liczby całkowitej.
|
|
|
+ * Przycina podaną wartość do podanego zakresu i zaokrągla do liczby całkowitej.
|
|
|
* To znaczy, że jeśli {@code value < min}, to zwraca {@code min}, jeśli
|
|
|
* {@code value > max}, to zwraca {@code max}, jeśli wartość mieści się w
|
|
|
- * podanym zakresie, to jest zwracana bez zmian.
|
|
|
+ * podanym zakresie, to jest zwracana bez zmian.
|
|
|
* @param value
|
|
|
* @param min
|
|
|
* @param max
|
|
|
@@ -108,12 +108,12 @@ public final class MathUtils {
|
|
|
assert min <= max;
|
|
|
return (int)Math.round(value < min ? min : value > max ? max : value);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
- * Przycina podaną wartość do podanego zakresu i zaokrągla do liczby całkowitej.
|
|
|
+ * Przycina podaną wartość do podanego zakresu i zaokrągla do liczby całkowitej.
|
|
|
* To znaczy, że jeśli {@code value < min}, to zwraca {@code min}, jeśli
|
|
|
* {@code value > max}, to zwraca {@code max}, jeśli wartość mieści się w
|
|
|
- * podanym zakresie, to jest zwracana bez zmian.
|
|
|
+ * podanym zakresie, to jest zwracana bez zmian.
|
|
|
* @param value
|
|
|
* @param min
|
|
|
* @param max
|
|
|
@@ -123,15 +123,15 @@ public final class MathUtils {
|
|
|
assert min <= max;
|
|
|
return Math.round(value < min ? min : value > max ? max : value);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
/**
|
|
|
* Alternate to signum for use in compare. Not a true signum, since it
|
|
|
* returns ints other than +/-1. Where there is any possibility of overflow,
|
|
|
- * you should compare two longs with < rather than subtraction.
|
|
|
+ * you should compare two longs with < rather than subtraction.
|
|
|
* <p>
|
|
|
* In Pentium assembler you could implement this algorthm with following code:
|
|
|
* <pre>
|
|
|
- * # diff = edx:eax
|
|
|
+ * # diff = edx:eax
|
|
|
* # result = eax
|
|
|
* mov ebx,eax
|
|
|
* shl eax,1
|
|
|
@@ -149,11 +149,11 @@ public final class MathUtils {
|
|
|
* or eax,edx
|
|
|
* </pre>
|
|
|
* This is 4 cycles, still one more than lohi. Why was Piotr so much
|
|
|
- * faster on JET? Peter has no pipeline-confounding jumps. Further, the lo
|
|
|
- * then high operands actually come from the ram-based stack. Piotr nicely
|
|
|
- * separates the accesses giving plenty of for pre-emptive fetch of hi.
|
|
|
- * lohi insists on having them both upfront, so it has to wait for memory
|
|
|
- * access. Piotr does not have to wait. Modern CPUS hurry up and wait for
|
|
|
+ * faster on JET? Peter has no pipeline-confounding jumps. Further, the lo
|
|
|
+ * then high operands actually come from the ram-based stack. Piotr nicely
|
|
|
+ * separates the accesses giving plenty of for pre-emptive fetch of hi.
|
|
|
+ * lohi insists on having them both upfront, so it has to wait for memory
|
|
|
+ * access. Piotr does not have to wait. Modern CPUS hurry up and wait for
|
|
|
* RAM most of the time.
|
|
|
* </p>
|
|
|
* @param diff number to be collapsed to an int preserving sign and
|
|
|
@@ -165,5 +165,21 @@ public final class MathUtils {
|
|
|
public static int signum(long diff) {
|
|
|
return (int) (diff >>> 32) | ((int) diff | (int) diff << 1) >>> 1;
|
|
|
}
|
|
|
+
|
|
|
+ public static int log2floor(int x) {
|
|
|
+ return 31 - Integer.numberOfLeadingZeros(x);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static int log2ceil(int x) {
|
|
|
+ return 32 - Integer.numberOfLeadingZeros(x - 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static int log2floor(long x) {
|
|
|
+ return 63 - Long.numberOfLeadingZeros(x);
|
|
|
+ }
|
|
|
+
|
|
|
+ public static int log2ceil(long x) {
|
|
|
+ return 64 - Long.numberOfLeadingZeros(x - 1);
|
|
|
+ }
|
|
|
}
|
|
|
|