Java имеет 2 оператора сдвига разряда для сдвигов вправо:
>> shifts right, and is dependant on the sign bit for the sign of the result
>>> shifts right and shifts a zero into leftmost bits
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op3.html
Это кажется довольно простым, так может любой объяснять мне, почему этот код при предоставлении значения-128 для панели производит значение-2 для нечто:
byte foo = (byte)((bar & ((byte)-64)) >>> 6);
То, что это предназначено, чтобы сделать, является взятием байт на 8 битов, маска крайних левых 2 битов, и сместите их в самые правые 2 бита. Т.е.:
initial = 0b10000000 (-128)
-64 = 0b11000000
initial & -64 = 0b10000000
0b10000000 >>> 6 = 0b00000010
Результат на самом деле-2, который является
0b11111110
Т.е. 1 с, а не нули смещается в оставленные должности
ItiveControl
является вашим другом:
<ItemsControl ItemsSource="{Binding YourChildItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
-121--1713818- Когда вы говорите C нравится, он идет в том же направлении, что и другие. Scala каким-то образом устраняет нули с помощью вариантов. Тем не менее, можно использовать нулевые значения. Функциональные языки не имеют нулевых проблем и побочных эффектов, но они не c как. Динамические языки также имеют значения null или неопределенные переменные и т. д. Это цена, которую вы должны заплатить за c, как imho.
-121--4460266- Это потому, что & на самом деле выполняет продвижение до int
- что оставляет ужасно много «1» битов. Затем вы смещаетесь вправо, оставляя самые левые 2 бита как 0, но затем игнорируете эти самые левые биты, возвращая их в байт.
Это становится более ясным, когда вы отделяете операции:
public class Test
{
public static void main(String[] args)
{
byte bar = -128;
int tmp = (bar & ((byte)-64)) >>> 6;
byte foo = (byte)tmp;
System.out.println(tmp);
System.out.println(foo);
}
}
печатает
67108862
-2
Так что сделать свой бит арифметика снова:
initial = 0b10000000 (-128)
-64 = 0b11000000
initial & -64 = 0b11111111111111111111111110000000 // it's an int now
0b10000000 >>> 6 = 0b00111111111111111111111111100000 // note zero-padding
(byte) (0b10000000 >>> 6) = 11100000 // -2
Даже если вы получите правильный результат из операции & (путем кастинга в тот пункт), > > >
будет продвигать первый операнд до int
в первую очередь.
EDIT: Решение состоит в том, чтобы изменить способ маскировки вещей. Вместо маскирования на -64 маска просто на 128 + 64 = 192 = 0xc0 вместо этого:
byte foo = (byte)((bar & 0xc0) >>> 6);
Это путь вы действительно получить только с двумя битами вы хотите, вместо того, чтобы иметь нагрузку 1 s в наиболее старших битов 24.
afaik, в Java большинство операторов (+, -, >> и т. Д.) Не может работать над тем, что меньше, чем int
s. Таким образом, ваши побитовые сдвиги и и
неявно отличаются значения в int
на заднем плане, а затем обратно в байт
вашим явным выбросом снаружи. Последний акт избавляется от нулей в более высоких битах.
Чтобы получить результаты, которые вы ожидаете, попробуйте делать это на int
S.
Другие говорили вам, почему, но я все сломут его и предоставим ответ на реальную проблему.
byte foo = (byte)((bar & ((byte)-64)) >>> 6);
Поскольку и оператор будет продвигать все, что это означает, что это делает, по сути:
byte foo = (byte)(((int)bar & (int)((byte)-64)) >>> 6);
, если стержень IS -128, затем (INT) BAR - это 0xFFFFFFFF80, который является затем и «с 0xFFFFFFF0, Затем вы сместите это правильное 6 мест, чтобы получить: 0x3ffffffe
Правильный ответ действительно прост:
byte foo = (byte)((bar & 0xC0) >> 6);
Бар продвигается в int для операции и операции, поэтому единственное, что осталось в том, что int int будет два верхних бита Оригинальный байт. Затем переместите его вправо 6 битов и преобразуйте его обратно в байты.