Неподписанный короткий в Java
Как я могу объявить unsigned short
значение в Java?
16 ответов
Вы не можете, правда. В Java нет типов данных без знака, кроме char
,
Правда, вы могли бы использовать char
- это 16-разрядный тип без знака - но это было бы ужасно, на мой взгляд, как char
явно предназначен для текста: когда код использует char
Я ожидаю, что он будет использовать его для кодовых единиц UTF-16, представляющих интересный для программы текст, а не произвольные 16-разрядные целые числа без знака без отношения к тексту.
Если вам действительно нужно значение с 16 битами:
Решение 1. Используйте доступное подписанное короткое замыкание и перестаньте беспокоиться о знаке, если только вам не нужно выполнять операции сравнения (<, <=,>,> =) или деления (/, %, >>). Посмотрите этот ответ, чтобы узнать, как обрабатывать подписанные номера, как если бы они были без знака.
Решение 2 (где решение 1 не применимо): используйте младшие 16 битов int и удалите старшие биты с помощью & 0xffff, где это необходимо.
Это действительно несвежая тема, но в интересах любого, кто придет после. Char является числовым типом. Он поддерживает все математические операторы, битовые операции и т. Д. Это 16 без знака.
Мы обрабатываем сигналы, записанные пользовательским встроенным оборудованием, поэтому мы обрабатываем большое количество беззнаковых 16 из A-D. Мы использовали символы повсюду в течение многих лет, и у нас никогда не было проблем.
Вы можете использовать символ, так как это 16-битное значение без знака (хотя технически это символ Юникода, поэтому в будущем он может измениться на 24-битное значение)... другая альтернатива - использовать int и убедиться, что это в пределах досягаемости.
Не используйте char - используйте int:-)
Из DataInputStream.java
public final int readUnsignedShort() throws IOException {
int ch1 = in.read();
int ch2 = in.read();
if ((ch1 | ch2) < 0)
throw new EOFException();
return (ch1 << 8) + (ch2 << 0);
}
Невозможно объявить тип unsigned short, но в моем случае мне нужно было получить число без знака, чтобы использовать его в цикле for. Есть метод
toUnsignedInt
в классе
Short
который возвращает « аргумент, преобразованный в int беззнаковым преобразованием »:
short signedValue = -4767;
System.out.println(signedValue ); // prints -4767
int unsignedValue = Short.toUnsignedInt(signedValue);
System.out.println(unsingedValue); // prints 60769
Аналогичные методы существуют для Integer и Long:
Integer.toUnsignedLong
Long.toUnsignedString
: В этом случае он заканчивается в
String
потому что нет большего числового типа.
Если можно использовать стороннюю библиотеку, есть jOOU (библиотека выделения из jOOQ), которая предлагает типы-оболочки для целых чисел без знака в Java. Это не совсем то же самое, что иметь поддержку примитивного типа (и, следовательно, байтового кода) для неподписанных типов, но, возможно, это все еще достаточно для вашего варианта использования.
import static org.joou.Unsigned.*;
// and then...
UShort s = ushort(1);
(Отказ от ответственности: я работаю на компанию за этими библиотеками)
Да нет, если вы хотите использовать значение в коде против битовых операций.
"В Java SE 8 и более поздних версиях вы можете использовать тип данных int для представления 32-разрядного целого числа без знака, которое имеет минимальное значение 0 и максимальное значение 232-1". Однако это относится только к int и long, но не к short:(
Нет, на самом деле такого метода не существует, Java - язык высокого уровня. Вот почему в Java нет неподписанных типов данных.
Он сказал, что хочет создать многомерный короткий массив. Еще никто не предлагал побитовые операторы? Из того, что я прочитал, вы хотите использовать 16-битные целые по 32-битным целым для экономии памяти?
Итак, во-первых, для начала 10 000 x 10 000 коротких значений -1 600 000 000 битов, 200 000 000 байтов, 200 000 килобайт, 200 мегабайт.
Если вам нужно что-то с 200 МБ памяти, вы можете изменить эту идею. Я тоже не верю, что буду даже компилировать, не говоря уже о запуске. Вы никогда не должны инициализировать большие массивы, как это, если что-либо использует 2 функции, называемые загрузкой по требованию и кэшированием данных. По сути, загрузка по требованию относится к идее загружать данные только по мере необходимости. Затем кэширование данных делает то же самое, но использует пользовательскую работу с кадрами для удаления старой памяти и добавления новой информации по мере необходимости. Это сложно иметь хорошие показатели скорости. Есть и другие вещи, которые вы можете сделать, но эти две мои любимые, когда все сделано правильно.
Хорошо, вернемся к тому, что я говорил о побитовых операторах.
Таким образом, 32-разрядное целое число или в Java "INT". Вы можете хранить то, что называется "битами", так что, скажем, у вас было 32 логических значения, которые в Java все значения занимают 32 бита (кроме длинных) или для массивов они принимают 8 для байтов, 16 для коротких и 32 для целых, Таким образом, если у вас нет массивов, вы не получите никакой выгоды от памяти, используя байт или шорт. Это не означает, что вы не должны использовать его как способ гарантировать, что вы и другие люди знают диапазон данных, который должно иметь это значение.
Теперь, как я уже говорил, вы можете эффективно хранить 32 логических значения в одно целое число, выполнив следующие действия:
int many_booleans = -1; //All are true;
int many_booleans = 0; //All are false;
int many_booleans = 1 | 2 | 8; //Bits 1, 2, and 4 are true the rest are false;
Итак, теперь короткое замыкание состоит из 16 битов, поэтому 16 + 16 = 32, который идеально подходит для 32-битного целого числа. Таким образом, каждое значение типа int может состоять из 2 коротких значений.
int two_shorts = value | (value2 << 16);
Таким образом, вышеприведенные действия заключаются в том, что значение находится в диапазоне от -32768 до 32767 или в виде значения без знака 0 - 65535. Итак, допустим, значение равно -1, так что в качестве значения без знака оно равно 65535. Это означает, что биты с 1 по 16 включены, но при фактическом выполнении математики учитывайте диапазон 0 - 15.
Поэтому нам нужно активировать биты 17 - 32. Поэтому мы должны начать с чего-то большего, чем 15 бит. Итак, мы начинаем с 16 бит. Итак, взяв значение 2 и умножив его на 65536, что и делает "<< 16". Теперь у нас есть, скажем, value2 равное 3, это будет OR'd 3x65536 = 196608. Таким образом, наше целочисленное значение будет равно 262143.
int assumed_value = 262143;
скажем, мы хотим получить два 16-битных целочисленных значения.
short value1 = (short)(assumed_value & 0xFFFF); //-1
short value2 = (short)(assumed_value >> 16); //=3
Также в основном думают о побитовых операторах как о степенях 2. Это все, что они есть на самом деле. Никогда не смотрите на это с точки зрения 0 и 1. В основном я писал об этом, чтобы помочь любому, кто может столкнуться с поиском неподписанных коротких или даже, возможно, многомерных массивов. Если есть какие-либо опечатки, я прошу прощения быстро написал это.
Простая программа, показывающая, зачем нужны беззнаковые числа:
package shifttest;
public class ShiftTest{
public static void main(String[] args){
short test = -15000;
System.out.format ("0x%04X 0x%04X 0x%04X 0x%04X 0x%04X\n",
test, test>>1, test>>2, test>>3, test>>4);
}
}
Результаты:
0xC568 0xFFFFE2B4 0xFFFFF15A 0xFFFFF8AD 0xFFFFFC56
Теперь для тех, которые не являются типами систем:
JAVA делает арифметический сдвиг, потому что операнд подписан, однако есть случаи, когда логический сдвиг был бы уместным, но JAVA (в частности, Sun) посчитал это ненужным, что слишком плохо для нас из-за их близорукости. Shift, And, Or и Exclusive Or являются ограниченными инструментами, когда все, что у вас есть, подписано более длинными номерами. Это является особой проблемой при взаимодействии с аппаратными устройствами, которые передают "РЕАЛЬНЫЕ" компьютерные биты размером 16 бит или более. "char" не гарантированно работает (теперь его ширина составляет два байта), но в некоторых восточных gif-языках, таких как китайский, корейский и японский, требуется как минимум 3 байта. Я не знаком с количеством нуждающихся в языках стиля Sandscript. Количество байтов не зависит от программиста, а от комитета по стандартам для JAVA. Таким образом, основание char как 16 битов имеет нисходящий риск. Для безопасной реализации неподписанных шорт JAVA, так как специальный класс - лучшее решение, основанное на вышеупомянутых неясностях. Недостатком класса является невозможность перегрузки математических операций для этого специального класса. Многие из участников этой ветки точно указали на эти проблемы, но мой вклад - пример рабочего кода и мой опыт работы с 3-байтовыми языками GIF-файлов в C++ под Linux.
Вы можете закодировать себя ShortUnsigned
Класс и определить методы для тех операторов, которые вы хотите. Вы не сможете перегрузить +
а также -
и другие на них, и, увы, не имеют неявного преобразования типов с другими примитивными или числовыми типами объектов.
Как и некоторым другим ответчикам, мне интересно, почему у вас острая необходимость в unsigned short, который не будет заполнен никаким другим типом данных.
//вот метод для получения аналога unsigned short
public static int getShortU(byte [] arr, int i ) throws Exception
{
try
{
byte [] b = new byte[2];
b[1] = arr[i];
b[0] = arr[i+1];
int k = ByteBuffer.wrap(b).getShort();
//if this:
//int k = ((int)b[0] << 8) + ((int)b[1] << 0);
//65536 = 2**16
if ( k <0) k = 65536+ k;
return k;
}
catch(Throwable t)
{
throw new Exception ("from getShort: i=" + i);
}
}
У Java нет неподписанных типов. Для чего тебе это?
Однако в Java есть тип данных "byte".