venu656 Ответов: 1

Вопрос об операторах сдвига битов


Привет Гуру

Я очень новичок в операторах побитового сдвига ,мне нужна ваша помощь в приведенном ниже коде

ulong unitDate = (((ulong)885478688974) << 32) + (ulong)20170111;
uint low = (uint)(unitDate & (ulong)uint.MaxValue);
uint high = (uint)(unitDate >> 32);


в переменной Low я получаю данные =20170111, что правильно
Но в переменной high я получаю значение 715425998 что неверно я должен получить значение 885478688974



Спасибо

Что я уже пробовал:

если идти с нижеприведенным кодом, то я получаю точные значения в переменной low и high. как обрабатывать данные, которые больше, чем 4294967295

ulong unitDate = (((ulong)4294967295) << 32) + (ulong)20170111;
uint low = (uint)(unitDate & (ulong)uint.MaxValue);
uint high = (uint)(unitDate >> 32);


ваша помощь будет оценена по достоинству

1 Ответов

Рейтинг:
2

Patrice T

Цитата:
Но в высокой переменной я получаю значение как 715425998 что не есть правильно

Нет, это правильно, просто надо понять почему.
Значение 885478688974 укладывается в 40 бит, затем вы сдвигаете его на 32 бита, результат должен быть 72 бита, но результат хранится в 64-битной переменной/регистре.
Это то, что называется переполнением, и последние 8 бит теряются.

[Обновление]
Надеюсь, это прояснит ситуацию.
Вы используете паром, чтобы пересечь озеро, на лодке есть место для 32 автомобилей.
Вы пытаетесь вместить 40 автомобилей. Сколько машин окажется в воде ?
Это проблема, с которой вы сталкиваетесь, это невозможно.


venu656

Спасибо PPolymorphe, тогда как получить точное значение ,не могли бы вы прислать мне, как это сделать, я очень сильно борюсь
Вот как выглядит мой точный код
ulong unitDate = (((ulong) unitID) < & lt; 32) + (ulong)localTimeStamp. Date;
uint с unitID = (uint с) (0xFFFFFFFF в &ампер; (unitDate &ГТ;&ГТ; 32));
uint localDate = (uint) (0xffffffff & unitDate);
если мой unitid меньше 4294967295, я получаю точные результаты, но когда он больше 4294967295, я не получаю точных результатов в unitid ,как обрабатывать эти результаты

Jochen Arndt

Вы не можете получить его, потому что биты теряются при создании unitDate.

То, что вы делаете,-это упаковка двух 32-битных значений в 64-битное. Их можно извлечь, выполнив обратные операции.

Но он работает только с входными значениями, которые не превышают 32 бита ( 4294967295 = 0xfffffff).

При таких операциях лучше использовать шестнадцатеричную нотацию, чтобы понять, что происходит (здесь с пробелами для лучшей читабельности):
885478688974 = CE 2AA4 88CE
CE 2AA4 88CE < & lt; 32 = CE 2AA4 88CE 0000 0000
Вышеприведенный результат имеет в общей сложности 72 бита, но хранится в улонге, который может содержать только 64 бита. Таким образом, верхние биты (здесь CE) теряются (смещаются). При выполнении обратной операции позже вы получите 2AA4 88CE для высокой части.

Чтобы прибить его к ногтю:
Ваш алгоритм ограничен 32-битными входными значениями. Если у вас есть большие значения, это не сработает.