mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Adds java.lang.Math and java.util.HashSet
This commit is contained in:
parent
9c4f00c18a
commit
cb0dd8e992
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.teavm.codegen.SourceWriter;
|
||||
import org.teavm.javascript.ni.Generator;
|
||||
import org.teavm.javascript.ni.GeneratorContext;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class MathNativeGenerator implements Generator {
|
||||
@Override
|
||||
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
||||
switch (methodRef.getName()) {
|
||||
case "sin":
|
||||
case "cos":
|
||||
case "tan":
|
||||
case "asin":
|
||||
case "acos":
|
||||
case "atan":
|
||||
case "exp":
|
||||
case "log":
|
||||
case "sqrt":
|
||||
case "floor":
|
||||
case "ceil":
|
||||
function(context, writer, "Math." + methodRef.getName(), methodRef.parameterCount());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void function(GeneratorContext context, SourceWriter writer, String name, int paramCount)
|
||||
throws IOException {
|
||||
writer.append("return ").append(name).append("(");
|
||||
for (int i = 0; i < paramCount; ++i) {
|
||||
if (i > 0) {
|
||||
writer.append(",").ws();
|
||||
}
|
||||
writer.append(context.getParameterName(i + 1));
|
||||
}
|
||||
writer.append(");").softNewLine();
|
||||
}
|
||||
}
|
|
@ -15,14 +15,94 @@
|
|||
*/
|
||||
package org.teavm.classlib.java.lang;
|
||||
|
||||
import org.teavm.javascript.ni.GeneratedBy;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public final class TMath extends TObject {
|
||||
public static double E = 2.71828182845904523536;
|
||||
public static double PI = 3.14159265358979323846;
|
||||
|
||||
private TMath() {
|
||||
}
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double sin(double a);
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double cos(double a);
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double tan(double a);
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double asin(double a);
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double acos(double a);
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double atan(double a);
|
||||
|
||||
public static double toRadians(double angdeg) {
|
||||
return angdeg * PI / 180;
|
||||
}
|
||||
|
||||
public static double toDegrees(double angrad) {
|
||||
return angrad * 180 / PI;
|
||||
}
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double exp(double a);
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double log(double a);
|
||||
|
||||
public static double log10(double a) {
|
||||
return log(a) / 2.302585092994046 /* log_e 10 */;
|
||||
}
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double sqrt(double a);
|
||||
|
||||
public static double cbrt(double a) {
|
||||
return a > 0 ? pow(a, 1.0 / 3) : -pow(-a, 1.0 / 3);
|
||||
}
|
||||
|
||||
public static double IEEEremainder(double f1, double f2) {
|
||||
int n = (int)(f1 / f2);
|
||||
return f1 - n * f2;
|
||||
}
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double ceil(double a);
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double floor(double a);
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double pow(double x, double y);
|
||||
|
||||
public static double rint(double a) {
|
||||
return round(a);
|
||||
}
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double atan2(double y, double x);
|
||||
|
||||
public static int round(float a) {
|
||||
return (int)(a + 1.5f);
|
||||
}
|
||||
|
||||
public static long round(double a) {
|
||||
return (long)(a + 0.5);
|
||||
}
|
||||
|
||||
@GeneratedBy(MathNativeGenerator.class)
|
||||
public static native double random();
|
||||
|
||||
public static int min(int a, int b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
@ -47,6 +127,14 @@ public final class TMath extends TObject {
|
|||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
public static float min(float a, float b) {
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
public static float max(float a, float b) {
|
||||
return a > b ? a : b;
|
||||
}
|
||||
|
||||
public static int abs(int n) {
|
||||
return n > 0 ? n : -n;
|
||||
}
|
||||
|
@ -55,7 +143,127 @@ public final class TMath extends TObject {
|
|||
return n > 0 ? n : -n;
|
||||
}
|
||||
|
||||
public static float abs(float n) {
|
||||
return n > 0 ? n : -n;
|
||||
}
|
||||
|
||||
public static double abs(double n) {
|
||||
return n > 0 ? n : -n;
|
||||
}
|
||||
|
||||
public static double ulp(double d) {
|
||||
return pow(1, -getExponent(d) - 52);
|
||||
}
|
||||
|
||||
public static float ulp(float d) {
|
||||
return (float)pow(1, -getExponent(d) - 23);
|
||||
}
|
||||
|
||||
public static double signum(double d) {
|
||||
return d > 0 ? 1 : d < -0 ? -1 : d;
|
||||
}
|
||||
|
||||
public static float signum(float d) {
|
||||
return d > 0 ? 1 : d < -0 ? -1 : d;
|
||||
}
|
||||
|
||||
public static double sinh(double x) {
|
||||
double e = exp(x);
|
||||
return e - 1 / e;
|
||||
}
|
||||
|
||||
public static double cosh(double x) {
|
||||
double e = exp(x);
|
||||
return e + 1 / e;
|
||||
}
|
||||
|
||||
public static double tanh(double x) {
|
||||
double e = exp(x);
|
||||
return (e - 1 / e) / (e + 1 / e);
|
||||
}
|
||||
|
||||
public static double hypot(double x, double y) {
|
||||
return x * x + y * y;
|
||||
}
|
||||
|
||||
public static double expm1(double x) {
|
||||
return exp(x) - 1;
|
||||
}
|
||||
|
||||
public static double log1p(double x) {
|
||||
return log(x + 1);
|
||||
}
|
||||
|
||||
public static float copySign(float magnitude, float sign) {
|
||||
if (sign == 0 || sign == -0) {
|
||||
return sign;
|
||||
}
|
||||
return (sign > 0) == (magnitude > 0) ? magnitude : -magnitude;
|
||||
}
|
||||
|
||||
public static double copySign(double magnitude, double sign) {
|
||||
if (sign == 0 || sign == -0) {
|
||||
return sign;
|
||||
}
|
||||
return (sign > 0) == (magnitude > 0) ? magnitude : -magnitude;
|
||||
}
|
||||
|
||||
public static int getExponent(double d) {
|
||||
d = abs(d);
|
||||
int exp = 0;
|
||||
double[] exponents = ExponentConstants.exponents;
|
||||
double[] negativeExponents = ExponentConstants.negativeExponents;
|
||||
if (d > 1) {
|
||||
int expBit = 1 << (exponents.length - 1);
|
||||
for (int i = exponents.length - 1; i >= 0; --i) {
|
||||
if (d > exponents[i]) {
|
||||
d *= negativeExponents[i];
|
||||
exp |= expBit;
|
||||
}
|
||||
expBit >>>= 1;
|
||||
}
|
||||
} else if (d < 1) {
|
||||
int expBit = 1 << (negativeExponents.length - 1);
|
||||
for (int i = negativeExponents.length - 1; i >= 0; --i) {
|
||||
if (d < negativeExponents[i]) {
|
||||
d *= exponents[i];
|
||||
exp |= expBit;
|
||||
}
|
||||
expBit >>>= 1;
|
||||
}
|
||||
exp = -exp;
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
public static int getExponent(float f) {
|
||||
return getExponent(f);
|
||||
}
|
||||
|
||||
public static double nextAfter(double start, double direction) {
|
||||
if (start == direction) {
|
||||
return direction;
|
||||
}
|
||||
return direction > start ? start + ulp(start) : start - ulp(start);
|
||||
}
|
||||
|
||||
public static float nextAfter(float start, float direction) {
|
||||
if (start == direction) {
|
||||
return direction;
|
||||
}
|
||||
return direction > start ? start + ulp(start) : start - ulp(start);
|
||||
}
|
||||
|
||||
public static double nextUp(double d) {
|
||||
return d + ulp(d);
|
||||
}
|
||||
|
||||
public static float nextUp(float d) {
|
||||
return d + ulp(d);
|
||||
}
|
||||
|
||||
private static class ExponentConstants {
|
||||
public static double[] exponents = { 1E1, 1E2, 1E4, 1E8, 1E16, 1E32, 1E64, 1E128, 1E256 };
|
||||
public static double[] negativeExponents = { 1E-1, 1E-2, 1E-4, 1E-8, 1E-16, 1E-32, 1E-64, 1E-128, 1E-256 };
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.util;
|
||||
|
||||
import org.teavm.classlib.java.io.TSerializable;
|
||||
import org.teavm.classlib.java.lang.TCloneNotSupportedException;
|
||||
import org.teavm.classlib.java.lang.TCloneable;
|
||||
import org.teavm.classlib.java.lang.TObject;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class THashSet<E> extends TAbstractSet<E> implements TCloneable, TSerializable {
|
||||
transient THashMap<E, THashSet<E>> backingMap;
|
||||
|
||||
/**
|
||||
* Constructs a new empty instance of {@code HashSet}.
|
||||
*/
|
||||
public THashSet() {
|
||||
this(new THashMap<E, THashSet<E>>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HashSet} with the specified capacity.
|
||||
*
|
||||
* @param capacity
|
||||
* the initial capacity of this {@code HashSet}.
|
||||
*/
|
||||
public THashSet(int capacity) {
|
||||
this(new THashMap<E, THashSet<E>>(capacity));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HashSet} with the specified capacity
|
||||
* and load factor.
|
||||
*
|
||||
* @param capacity
|
||||
* the initial capacity.
|
||||
* @param loadFactor
|
||||
* the initial load factor.
|
||||
*/
|
||||
public THashSet(int capacity, float loadFactor) {
|
||||
this(new THashMap<E, THashSet<E>>(capacity, loadFactor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of {@code HashSet} containing the unique
|
||||
* elements in the specified collection.
|
||||
*
|
||||
* @param collection
|
||||
* the collection of elements to add.
|
||||
*/
|
||||
public THashSet(TCollection<? extends E> collection) {
|
||||
this(new THashMap<E, THashSet<E>>(collection.size() < 6 ? 11 : collection.size() * 2));
|
||||
for (TIterator<? extends E> iter = collection.iterator(); iter.hasNext();) {
|
||||
add(iter.next());
|
||||
}
|
||||
}
|
||||
|
||||
THashSet(THashMap<E, THashSet<E>> backingMap) {
|
||||
this.backingMap = backingMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified object to this {@code HashSet} if not already present.
|
||||
*
|
||||
* @param object
|
||||
* the object to add.
|
||||
* @return {@code true} when this {@code HashSet} did not already contain
|
||||
* the object, {@code false} otherwise
|
||||
*/
|
||||
@Override
|
||||
public boolean add(E object) {
|
||||
return backingMap.put(object, this) == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all elements from this {@code HashSet}, leaving it empty.
|
||||
*
|
||||
* @see #isEmpty
|
||||
* @see #size
|
||||
*/
|
||||
@Override
|
||||
public void clear() {
|
||||
backingMap.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new {@code HashSet} with the same elements and size as this
|
||||
* {@code HashSet}.
|
||||
*
|
||||
* @return a shallow copy of this {@code HashSet}.
|
||||
* @see java.lang.Cloneable
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public TObject clone() {
|
||||
try {
|
||||
THashSet<E> clone = (THashSet<E>) super.clone();
|
||||
clone.backingMap = (THashMap<E, THashSet<E>>)backingMap.clone();
|
||||
return clone;
|
||||
} catch (TCloneNotSupportedException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches this {@code HashSet} for the specified object.
|
||||
*
|
||||
* @param object
|
||||
* the object to search for.
|
||||
* @return {@code true} if {@code object} is an element of this
|
||||
* {@code HashSet}, {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean contains(Object object) {
|
||||
return backingMap.containsKey(object);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this {@code HashSet} has no elements, false otherwise.
|
||||
*
|
||||
* @return {@code true} if this {@code HashSet} has no elements,
|
||||
* {@code false} otherwise.
|
||||
* @see #size
|
||||
*/
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return backingMap.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an Iterator on the elements of this {@code HashSet}.
|
||||
*
|
||||
* @return an Iterator on the elements of this {@code HashSet}.
|
||||
* @see Iterator
|
||||
*/
|
||||
@Override
|
||||
public TIterator<E> iterator() {
|
||||
return backingMap.keySet().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified object from this {@code HashSet}.
|
||||
*
|
||||
* @param object
|
||||
* the object to remove.
|
||||
* @return {@code true} if the object was removed, {@code false} otherwise.
|
||||
*/
|
||||
@Override
|
||||
public boolean remove(Object object) {
|
||||
return backingMap.remove(object) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this {@code HashSet}.
|
||||
*
|
||||
* @return the number of elements in this {@code HashSet}.
|
||||
*/
|
||||
@Override
|
||||
public int size() {
|
||||
return backingMap.size();
|
||||
}
|
||||
|
||||
THashMap<E, THashSet<E>> createBackingMap(int capacity, float loadFactor) {
|
||||
return new THashMap<>(capacity, loadFactor);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2014 Alexey Andreev.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.teavm.classlib.java.lang;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class MathTest {
|
||||
@Test
|
||||
public void sinComputed() {
|
||||
assertEquals(0.90929742682568, Math.sin(2), 1E-14);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expComputed() {
|
||||
assertEquals(3.4212295362896734, Math.exp(1.23), 1E-14);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cbrtComputed() {
|
||||
assertEquals(3.0, Math.cbrt(27.0), 1E-14);
|
||||
assertEquals(-3.0, Math.cbrt(-27.0), 1E-14);
|
||||
assertEquals(0, Math.cbrt(0), 1E-14);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ulpComputed() {
|
||||
assertEquals(1.4210854715202004e-14, Math.ulp(123.456), 1E-25);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sinhComputed() {
|
||||
assertEquals(1.3097586593745313E53, Math.sinh(123), 1E40);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getExponentComputed() {
|
||||
assertEquals(6, Math.getExponent(123.456));
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user