Fix to[Hex/Octal/Binary]String for unsigned values

This commit is contained in:
Alexey Andreev 2018-01-28 18:06:12 +03:00
parent 06f8ed6a7c
commit 4ebaf476fe
4 changed files with 81 additions and 6 deletions
classlib/src/main/java/org/teavm/classlib
tests/src/test/java/org/teavm/classlib/java/lang

View File

@ -0,0 +1,43 @@
/*
* Copyright 2018 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.impl;
import org.teavm.classlib.java.lang.TCharacter;
public final class IntegerUtil {
private IntegerUtil() {
}
public static String toUnsignedLogRadixString(int value, int radixLog2, int size) {
if (value == 0) {
return "0";
}
int radix = 1 << radixLog2;
int mask = radix - 1;
int sz = (size - Integer.numberOfLeadingZeros(value) + radixLog2 - 1) / radixLog2;
char[] chars = new char[sz];
int pos = (sz - 1) * radixLog2;
int target = 0;
while (pos >= 0) {
chars[target++] = TCharacter.forDigit((value >>> pos) & mask, radix);
pos -= radixLog2;
}
return new String(chars);
}
}

View File

@ -15,6 +15,8 @@
*/
package org.teavm.classlib.java.lang;
import static org.teavm.classlib.impl.IntegerUtil.toUnsignedLogRadixString;
public class TInteger extends TNumber implements TComparable<TInteger> {
public static final int SIZE = 32;
public static final int MIN_VALUE = 0x80000000;
@ -39,15 +41,15 @@ public class TInteger extends TNumber implements TComparable<TInteger> {
}
public static String toHexString(int i) {
return toString(i, 16);
return toUnsignedLogRadixString(i, 4, SIZE);
}
public static String toOctalString(int i) {
return toString(i, 8);
return toUnsignedLogRadixString(i, 3, SIZE);
}
public static String toBinaryString(int i) {
return toString(i, 2);
return toUnsignedLogRadixString(i, 1, SIZE);
}
public static String toString(int i) {

View File

@ -172,15 +172,35 @@ public class TLong extends TNumber implements TComparable<TLong> {
}
public static String toHexString(long i) {
return toString(i, 16);
return toUnsignedLogRadixString(i, 4);
}
public static String toOctalString(long i) {
return toString(i, 8);
return toUnsignedLogRadixString(i, 3);
}
public static String toBinaryString(long i) {
return toString(i, 2);
return toUnsignedLogRadixString(i, 1);
}
private static String toUnsignedLogRadixString(long value, int radixLog2) {
if (value == 0) {
return "0";
}
int radix = 1 << radixLog2;
int mask = radix - 1;
int sz = (SIZE - numberOfLeadingZeros(value) + radixLog2 - 1) / radixLog2;
char[] chars = new char[sz];
long pos = (sz - 1) * radixLog2;
int target = 0;
while (pos >= 0) {
chars[target++] = TCharacter.forDigit((int) (value >>> pos) & mask, radix);
pos -= radixLog2;
}
return new String(chars);
}
public static String toString(long value) {

View File

@ -150,4 +150,14 @@ public class IntegerTest {
assertNull(Integer.getInteger("test.baz"));
assertNull(Integer.getInteger(null));
}
@Test
public void toHex() {
assertEquals("0", Integer.toHexString(0));
assertEquals("1", Integer.toHexString(1));
assertEquals("a", Integer.toHexString(10));
assertEquals("11", Integer.toHexString(17));
assertEquals("ff", Integer.toHexString(255));
assertEquals("ffffffff", Integer.toHexString(-1));
}
}