В прошлый раз, когда я проверил, следующее были пустые/пустые элементы, перечисленные в HTML5.
Допустимый для авторов: область, основа, br, седло, команда, встраивает, eventsource, час, img, ввела, связывается, meta, параметрический усилитель, источник
Недопустимый для авторов: basefont, bgsound, кадр, распорная деталь, wbr
Помимо некоторых, которые являются новыми в HTML5, который должен дать Вам общее представление о, которые могли бы поддерживаться при обслуживании XHTML в качестве текста/HTML. (Просто протестируйте их путем исследования произведенного DOM.)
Что касается XHTML служил application/xhtml+xml (который делает его XML), правила XML применяются, и любой элемент может быть пустым (даже при том, что DTD XHTML не может выразить этого).
Это должно работать:
int original = ...;
byte[] bytes = BitConverter.GetBytes(original);
short firstHalf = BitConverter.ToInt16(bytes, 0);
short secondHalf = BitConverter.ToInt16(bytes, 2);
РЕДАКТИРОВАТЬ:
протестировано с 0x7FFFFFFF, оно работает
byte[] recbytes = new byte[4];
recbytes[0] = BitConverter.GetBytes(firstHalf)[0];
recbytes[1] = BitConverter.GetBytes(firstHalf)[1];
recbytes[2] = BitConverter.GetBytes(secondHalf)[0];
recbytes[3] = BitConverter.GetBytes(secondHalf)[1];
int reconstituted = BitConverter.ToInt32(recbytes, 0);
Это, безусловно, можно сделать без потери информации. В обоих случаях вы получаете 32 бита информации. Независимо от того, используются они для знаковых битов или нет, не имеет значения:
int original = ...;
short firstHalf = (short) (original >> 16);
short secondHalf = (short) (original & 0xffff);
int reconstituted = (firstHalf << 16) | (secondHalf & 0xffff);
Здесь восстановленный
всегда будет равен исходному
, следовательно, информация не будет потеряна.
Теперь значение знаков двух коротких замыканий - другое дело - firstHalf
будет отрицательным, если и только если исходный
отрицателен, но secondHalf
будет отрицательным, если бит 15 (считая 0-31) из оригинала
установлено, что не имеет особого смысла в исходной форме.
Ответ Джона , переведенный на Visual Basic и без переполнения:
Module Module1
Function MakeSigned(ByVal x As UInt16) As Int16
Dim juniorBits As Int16 = CType(x And &H7FFF, Int16)
If x > Int16.MaxValue Then
Return juniorBits + Int16.MinValue
End If
Return juniorBits
End Function
Sub Main()
Dim original As Int32 = &H7FFFFFFF
Dim firstHalfUnsigned As UInt16 = CType(original >> 16, UInt16)
Dim secondHalfUnsigned As UInt16 = CType(original And &HFFFF, UInt16)
Dim firstHalfSigned As Int16 = MakeSigned(firstHalfUnsigned)
Dim secondHalfSigned As Int16 = MakeSigned(secondHalfUnsigned)
Console.WriteLine(firstHalfUnsigned)
Console.WriteLine(secondHalfUnsigned)
Console.WriteLine(firstHalfSigned)
Console.WriteLine(secondHalfSigned)
End Sub
End Module
Результаты:
32767
65535
32767
-1
В .NET CType (& Hffff, Int16)
вызывает переполнение , а (короткий) 0xffff
дает -1 (без переполнения). Это связано с тем, что по умолчанию компилятор C # использует непроверенные операции, а VB.NET проверяется.
Лично мне нравится ответ Агга , потому что мой код более сложен, а код Джона вызовет исключение переполнения в проверено .
Я также создал еще один ответ , основанный на коде класса BitConverter
, оптимизированном для этой конкретной задачи. Однако он использует небезопасный код.
Если вы используете c ++, вас также могут заинтересовать StructLayout или объединения.
Из-за хранилища width (32 и 16 бит), преобразование Int32 в Int16 может означать потерю информации, если ваш Int32 больше 32767.
Почему нет? Давайте уменьшим количество битов для простоты: допустим, у нас есть 8 бит, из которых левый бит - минусовый бит.
[1001 0110] // representing -22
Вы можете сохранить его в 2 раза по 4 бита
[1001] [0110] // representing -1 and 6
Я не понимаю, почему это было бы невозможно, у вас дважды есть 8-битная информация
РЕДАКТИРОВАТЬ: Для простоты я не просто уменьшил биты, но и не использую метод 2-дополнительных. В моих примерах левый бит обозначает минус,
Если вы посмотрите на битовое представление, то вы правы.
Вы можете сделать это с целыми числами без знака, поскольку они не имеют знакового бита.
да, это можно сделать, используя маскирование и битовые сдвиги
Int16 a,b;
Int32 c;
a = (Int16) (c&0xffff);
b = (Int16) ((c>>16)&0xffff);
EDIT
, чтобы ответить на комментарий. Реконструкция работает нормально:
Int16 a, b;
Int32 c = -1;
a = (Int16)(c & 0xffff);
b = (Int16)((c >> 16) & 0xffff);
Int32 reconst = (((Int32)a)&0xffff) | ((Int32)b << 16);
Console.WriteLine("reconst = " + reconst);
Протестировано, как и ожидалось, выдает -1.
РЕДАКТИРОВАТЬ2: изменена реконструкция. Повышение Int16 до Int32 привело к расширению всех битов знака. Забыл об этом, его нужно было связать И.
Вы можете использовать StructLayout в VB.NET:
исправление: слово - 16 бит, двойное слово - 32 бит
<StructLayout(LayoutKind.Explicit, Size:=4)> _
Public Structure UDWord
<FieldOffset(0)> Public Value As UInt32
<FieldOffset(0)> Public High As UInt16
<FieldOffset(2)> Public Low As UInt16
Public Sub New(ByVal value As UInt32)
Me.Value = value
End Sub
Public Sub New(ByVal high as UInt16, ByVal low as UInt16)
Me.High = high
Me.Low = low
End Sub
End Structure
Подпись будет такой же, только вместо этого используются эти типы
<StructLayout(LayoutKind.Explicit, Size:=4)> _
Public Structure DWord
<FieldOffset(0)> Public Value As Int32
<FieldOffset(0)> Public High As Int16
<FieldOffset(2)> Public Low As Int16
Public Sub New(ByVal value As Int32)
Me.Value = value
End Sub
Public Sub New(ByVal high as Int16, ByVal low as Int16)
Me.High = high
Me.Low = low
End Sub
End Structure
РЕДАКТИРОВАТЬ:
Я как бы торопился несколько раз публиковал / редактировал свой ответ, но еще не объяснил это решение, так что я чувствую, что не завершил свой ответ. Итак, я собираюсь сделать это сейчас:
Использование StructLayout в явном виде в структуре требует, чтобы вы указали расположение каждого поля (по смещению в байтах) [StructLayoutAttribute] с атрибутом FieldOffset [FieldOffsetAttribute]
С помощью этих двух атрибутов вы можете создавать перекрывающиеся поля, также известные как объединения .
Первое поле (DWord.Value) будет 32-битным целым числом со смещением 0 (нуль). Чтобы разделить это 32-битное целое число, у вас должно быть два дополнительных поля, начинающихся снова со смещения 0 (ноль), а затем второе поле на 2 байта дальше, потому что 16-битное (короткое) целое число равно 2 байтам.
Из того, что я напомним, обычно, когда вы разделяете целое число, они обычно называют первую половину «высокой», а вторую половину - «низкой»; таким образом назвав два моих других поля.
Используя такую структуру, вы могли бы затем создать перегрузки для операторов и сужение / сужение типов, чтобы легко переходить от типа Int32 к этой структуре DWord, а также к сравнениям Оператор Перегрузка в VB.NET
Небезопасный код в C #, переполнение не происходит, автоматическое определение порядка байтов:
using System;
class Program
{
static void Main(String[] args)
{
checked // Yes, it works without overflow!
{
Int32 original = Int32.MaxValue;
Int16[] result = GetShorts(original);
Console.WriteLine("Original int: {0:x}", original);
Console.WriteLine("Senior Int16: {0:x}", result[1]);
Console.WriteLine("Junior Int16: {0:x}", result[0]);
Console.ReadKey();
}
}
static unsafe Int16[] GetShorts(Int32 value)
{
byte[] buffer = new byte[4];
fixed (byte* numRef = buffer)
{
*((Int32*)numRef) = value;
if (BitConverter.IsLittleEndian)
return new Int16[] { *((Int16*)numRef), *((Int16*)numRef + 1) };
return new Int16[] {
(Int16)((numRef[0] << 8) | numRef[1]),
(Int16)((numRef[2] << 8) | numRef[3])
};
}
}
}