Это должно быть намного быстрее для использования метод Newton для вычисления Целочисленный Квадратный корень , затем возвести в квадрат это число и проверку, как Вы делаете в своем текущем решении. Метод Newton является основанием для решения Carmack, упомянутого в некоторых других ответах. Необходимо быть в состоянии получить более быстрый ответ, так как Вы только интересуетесь целой частью корня, позволяя Вам остановить алгоритм аппроксимации раньше.
Другая оптимизация, которую можно попробовать: Если Цифровой Корень из числа не заканчивается в 1, 4, 7, или 9, число не полный квадрат. Это может использоваться в качестве быстрого способа устранить 60% Ваших исходных данных прежде, чем применить более медленный алгоритм квадратного корня.
CF Marshaler не очень хорош в этом типе вещей, и то, что вы пытаетесь сделать, не поддерживается. Проблема в том, что он знает, что первый элемент не выровнен, но, кажется, не понимает, что каждый элемент в массиве также будет невыровненным.
Вы можете увидеть, как работает этот пример:
[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct Message
{
[FieldOffset(0)]
public ushort X;
[FieldOffset(2)]
private ushort Y1;
[MarshalAs(UnmanagedType.LPArray)]
[FieldOffset(4)]
private ushort[] Y2;
[FieldOffset(12)]
public ushort Z;
}
Для этого типа структуру, я никогда не позволяю маршаллеру пытаться обработать каждого из членов. Структура небольшая, поэтому разбейте каждый отдельный элемент следующим образом:
[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct Message
{
[FieldOffset(0)]
public ushort X;
[FieldOffset(2)]
private ushort Y1;
[FieldOffset(4)]
private ushort Y2;
[FieldOffset(6)]
private ushort Y3;
[FieldOffset(8)]
private ushort Y4;
[FieldOffset(10)]
private ushort Y5;
[FieldOffset(12)]
public ushort Z;
}
или используйте имитацию «объединения», например:
public struct Y
{
public ushort a;
public ushort b;
public ushort c;
public ushort d;
public ushort e;
}
[StructLayout(LayoutKind.Explicit, Size = 14)]
public struct Message
{
[FieldOffset(0)]
public ushort X;
[FieldOffset(2)]
private Y Y;
[FieldOffset(12)]
public ushort Z;
}
Проблема возникает из-за того, что ваш массив перекрывает «X». ulong в C # - это UInt64 (в C ++ ulong - это UInt32), поэтому на самом деле это 8 байтов.
Если вы измените второе поле FieldOffset на 8 или измените X на uint, это исчезнет.