/*
Реализация среды исполнения языка программирования
Объектно-ориентированный продвинутый векторный транслятор
Copyright © 2021, 2024 Малик Разработчик
Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
общественной лицензии GNU.
Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<https://www.gnu.org/licenses/>.
*/
package avt.lang;
import avt.lang.array.*;
public final class Long(Object, Numeric, Comparable, Cloneable)
{
public static final long MIN_VALUE = 0x8000000000000000L;
public static final long MAX_VALUE = 0x7fffffffffffffffL;
public static native byte8 toByte8Bits(long value);
public static native short4 toShort4Bits(long value);
public static native int signum(long value);
public static native int compare(long value0, long value1);
public static native int compareUnsigned(long value0, long value1);
public static native int2 toInt2Bits(long value);
public static native long max(long value0, long value1);
public static native long maxUnsigned(long value0, long value1);
public static native long min(long value0, long value1);
public static native long minUnsigned(long value0, long value1);
public static native long rotateLeft(long value, int bits);
public static native long rotateRight(long value, int bits);
public static long parse(CharArray string) { return parse(string, 10); }
public static long parse(CharArray string, int radix) {
int length = string == null ? 0 : string.length;
if(length <= 0)
{
throw new NumberFormatException(package.getResourceString("illegal-argument.number-format"));
}
if(radix < Char.MIN_RADIX || radix > Char.MAX_RADIX)
{
throw new NumberFormatException(String.format(package.getResourceString("illegal-argument.number-format.radix"), new Object[] { new Int(radix) }));
}
boolean negative = false;
int index = 0;
long limit = 0x8000000000000001L;
if(string[0] == '-')
{
negative = true;
limit--;
index++;
}
long longradix = radix;
long mulmin = limit / longradix;
long result = 0;
if(index < length)
{
long digit = Char.toDigit(string[index++], radix);
if(digit < 0L)
{
throw new NumberFormatException(package.getResourceString("illegal-argument.number-format"));
}
result = -digit;
}
while(index < length)
{
long digit = Char.toDigit(string[index++], radix);
if(digit < 0L || result < mulmin || (result *= longradix) < limit + digit)
{
throw new NumberFormatException(package.getResourceString("illegal-argument.number-format"));
}
result -= digit;
}
if(negative)
{
if(index <= 1)
{
throw new NumberFormatException(package.getResourceString("illegal-argument.number-format"));
}
return result;
}
return -result;
}
public static long parseUnsigned(CharArray string) { return parseUnsigned(string, 10); }
public static long parseUnsigned(CharArray string, int radix) {
int length = string == null ? 0 : string.length;
if(length <= 0)
{
throw new NumberFormatException(package.getResourceString("illegal-argument.number-format"));
}
if(radix < Char.MIN_RADIX || radix > Char.MAX_RADIX)
{
throw new NumberFormatException(String.format(package.getResourceString("illegal-argument.number-format.radix"), new Object[] { new Int(radix) }));
}
int index = 1;
long longradix = radix;
long mulmin = 0xffffffffffffffffL // longradix;
long result = Char.toDigit(string[0], radix);
if(result < 0)
{
throw new NumberFormatException(package.getResourceString("illegal-argument.number-format"));
}
while(index < length)
{
long digit = Char.toDigit(string[index++], radix);
if(digit < 0L || compareUnsigned(result, mulmin) > 0 || compareUnsigned(result *= longradix, 0xffffffffffffffffL - digit) > 0)
{
throw new NumberFormatException(package.getResourceString("illegal-argument.number-format"));
}
result += digit;
}
return result;
}
public static native double toDoubleBits(long value);
public static String toBinaryString(long value) { return toShiftUnsignedString(value, 1); }
public static String toOctalString(long value) { return toShiftUnsignedString(value, 3); }
public static String toHexString(long value) { return toShiftUnsignedString(value, 4); }
public static String toString(long value) { return toString(value, 10); }
public static String toString(long value, int radix) {
boolean negative = value < 0L;
int index = 64;
int length = index + 1;
char[] buffer = new char[length];
if(radix < Char.MIN_RADIX || radix > Char.MAX_RADIX) radix = 10;
if(!negative) value = -value;
for(long longradix = radix, long negradix = -longradix; value <= negradix; value /= longradix) buffer[index--] = Char.toChar((int) -(value % longradix));
buffer[index] = Char.toChar((int) -value);
if(negative) buffer[--index] = '-';
return new String(buffer, index, length - index);
}
public static String toUnsignedString(long value) { return toUnsignedString(value, 10); }
public static String toUnsignedString(long value, int radix) {
int index = 63;
int length = index + 1;
char[] buffer = new char[length];
if(radix < Char.MIN_RADIX || radix > Char.MAX_RADIX) radix = 10;
for(long longradix = radix; compareUnsigned(value, longradix) >= 0; value //= longradix) buffer[index--] = Char.toChar((int) (value %% longradix));
buffer[index] = Char.toChar((int) value);
return new String(buffer, index, length - index);
}
public static String toLeadZeroString(long value, int width) { return toLeadZeroString(value, width, 10); }
public static String toLeadZeroString(long value, int width, int radix) {
boolean negative = value < 0L;
int index = 64;
int length = index + 1;
char[] buffer = new char[length];
if(width > index) width = index;
if(radix < Char.MIN_RADIX || radix > Char.MAX_RADIX) radix = 10;
if(!negative) value = -value;
for(long longradix = radix, long negradix = -longradix; value <= negradix; value /= longradix) buffer[index--] = Char.toChar((int) -(value % longradix));
buffer[index] = Char.toChar((int) -value);
for(int count = length - index; count < width; count++) buffer[--index] = '0';
if(negative) buffer[--index] = '-';
return new String(buffer, index, length - index);
}
public static Long valueOf(byte value) { return new Long(value); }
public static Long valueOf(short value) { return new Long(value); }
public static Long valueOf(int value) { return new Long(value); }
public static Long valueOf(long value) { return new Long(value); }
public static Long valueOf(float value) { return new Long(value); }
public static Long valueOf(double value) { return new Long(value); }
public static Long valueOf(real value) { return new Long(value); }
public static Long valueOf(CharArray string) {
long value = parse(string, 10);
return new Long(value);
}
public static Long valueOf(CharArray string, int radix) {
long value = parse(string, radix);
return new Long(value);
}
private static String toShiftUnsignedString(long value, int shift) {
int index = 64;
int length = index;
int mask = (1 << shift) - 1;
char[] buffer = new char[length];
do
{
buffer[--index] = Char.toChar((int) value & mask);
} while((value >>>= shift) != 0L);
return new String(buffer, index, length - index);
}
private final long fldValue;
public (byte value) { fldValue = value; }
public (short value) { fldValue = value; }
public (int value) { fldValue = value; }
public (long value) { fldValue = value; }
public (float value) { fldValue = (long) value; }
public (double value) { fldValue = (long) value; }
public (real value) { fldValue = (long) value; }
public boolean equals(Object anot) { return anot == this || anot instanceof Long && ((Long) anot).fldValue == fldValue; }
public int hashCode() {
long hash = fldValue;
return (int) (hash ^ (hash >> 32));
}
public long hashCodeAsLong() { return fldValue; }
public String toString() { return toString(fldValue, 10); }
public byte asByte() { return (byte) fldValue; }
public byte2 asByte2() { return (byte) fldValue; }
public byte4 asByte4() { return (byte) fldValue; }
public byte8 asByte8() { return (byte) fldValue; }
public short asShort() { return (short) fldValue; }
public short2 asShort2() { return (short) fldValue; }
public short4 asShort4() { return (short) fldValue; }
public short8 asShort8() { return (short) fldValue; }
public int asInt() { return (int) fldValue; }
public int2 asInt2() { return (int) fldValue; }
public int4 asInt4() { return (int) fldValue; }
public int8 asInt8() { return (int) fldValue; }
public long asLong() { return fldValue; }
public long2 asLong2() { return fldValue; }
public long4 asLong4() { return fldValue; }
public long8 asLong8() { return fldValue; }
public float asFloat() { return (float) fldValue; }
public float2 asFloat2() { return (float) fldValue; }
public float4 asFloat4() { return (float) fldValue; }
public float8 asFloat8() { return (float) fldValue; }
public double asDouble() { return (double) fldValue; }
public double2 asDouble2() { return (double) fldValue; }
public double4 asDouble4() { return (double) fldValue; }
public double8 asDouble8() { return (double) fldValue; }
public real asReal() { return fldValue; }
public int compareTo(Comparable anot) { return anot == this ? EQUALS : !(anot instanceof Long) ? INDEFINITE : compare(fldValue, ((Long) anot).fldValue); }
public Long clone() { return new Long(fldValue); }
public int kind { read = Class.LONG }
public long longValue { read = fldValue }
}