移位后无法取回正确的值
Can't get proper value back after shifting bits
我正在尝试通过解决一些具体问题来深入了解按位运算符。我得到的一个有趣的方法是首先将几个数字存储到一个变量中,然后将这些数字写回。存储的是一个日期,显然,它由日数、月数和年数组成。
我将一个变量声明为整数,因为32位是最小的变量大小,足以存储1到12的一个值,1到31的一个值和1到9999的一个值。
接下来,我从控制台输入 Integer 变量的 "day" 部分并将其分配给所述变量。在那之后,我将位向左移动 4 个位置,这使我在右侧留下 4 个空闲位来存储 "month" 部分。然后,我从控制台输入月份值,并将值(变量 OR console_input)分配给我的变量。之后,我将所有内容向右移动 14 位,以允许年份的值为 1 到 9999,并执行另一个 OR 运算以将值分配给移位释放的 14 位。
之后我将值输出到控制台,方法是向右移回与我输出的日期部分相关的所需时间量,然后将其与所需的数字进行翻转,以翻转剩下的所有内容该部分最左边的位为 0 并由此获得输入的日、月和年的值。
如果我的描述不够清楚,我很抱歉,但希望您通过查看随附的代码能够理解我的意思。我遇到的问题是日期和月份值显示正确,但我总是得到错误的年份,我根本不明白为什么。非常感谢任何帮助!
Dim inputDate As Integer
Console.WriteLine("Day: ")
inputDate = Console.ReadLine()
inputDate = (inputDate << 4)
Console.WriteLine("Month: ")
inputDate = (inputDate Or Console.ReadLine())
inputDate = (inputDate << 14)
Console.WriteLine("Year: ")
inputDate = (inputDate Or Console.ReadLine())
Console.WriteLine("Day: {0}. Month: {1}. Year: {2}", ((inputDate >> 18) And 31), ((inputDate >> 14) And 15), (inputDate And 9999))
我认为您的问题出在最后一行。
您正在使用生成所有 1
的二进制值来屏蔽 Day
和 Month
。
但是,您没有正确掩盖您的年份。
9,999 是 10 0111 0000 1111
的二进制,这意味着当 AND
在一起时,您保证某些位将保持 0
。
这将导致这一年产生有缺陷的结果。如果您正在寻找 14 位年份格式,则需要使用 2^14 - 1
进行屏蔽,即 16,383
,即二进制形式的 11 1111 1111 1111
。
注意31和15遵循相同的原则:
15 = 1111
,以及 31 = 11111
希望对您有所帮助!
我正在尝试通过解决一些具体问题来深入了解按位运算符。我得到的一个有趣的方法是首先将几个数字存储到一个变量中,然后将这些数字写回。存储的是一个日期,显然,它由日数、月数和年数组成。
我将一个变量声明为整数,因为32位是最小的变量大小,足以存储1到12的一个值,1到31的一个值和1到9999的一个值。
接下来,我从控制台输入 Integer 变量的 "day" 部分并将其分配给所述变量。在那之后,我将位向左移动 4 个位置,这使我在右侧留下 4 个空闲位来存储 "month" 部分。然后,我从控制台输入月份值,并将值(变量 OR console_input)分配给我的变量。之后,我将所有内容向右移动 14 位,以允许年份的值为 1 到 9999,并执行另一个 OR 运算以将值分配给移位释放的 14 位。
之后我将值输出到控制台,方法是向右移回与我输出的日期部分相关的所需时间量,然后将其与所需的数字进行翻转,以翻转剩下的所有内容该部分最左边的位为 0 并由此获得输入的日、月和年的值。
如果我的描述不够清楚,我很抱歉,但希望您通过查看随附的代码能够理解我的意思。我遇到的问题是日期和月份值显示正确,但我总是得到错误的年份,我根本不明白为什么。非常感谢任何帮助!
Dim inputDate As Integer
Console.WriteLine("Day: ")
inputDate = Console.ReadLine()
inputDate = (inputDate << 4)
Console.WriteLine("Month: ")
inputDate = (inputDate Or Console.ReadLine())
inputDate = (inputDate << 14)
Console.WriteLine("Year: ")
inputDate = (inputDate Or Console.ReadLine())
Console.WriteLine("Day: {0}. Month: {1}. Year: {2}", ((inputDate >> 18) And 31), ((inputDate >> 14) And 15), (inputDate And 9999))
我认为您的问题出在最后一行。
您正在使用生成所有 1
的二进制值来屏蔽 Day
和 Month
。
但是,您没有正确掩盖您的年份。
9,999 是 10 0111 0000 1111
的二进制,这意味着当 AND
在一起时,您保证某些位将保持 0
。
这将导致这一年产生有缺陷的结果。如果您正在寻找 14 位年份格式,则需要使用 2^14 - 1
进行屏蔽,即 16,383
,即二进制形式的 11 1111 1111 1111
。
注意31和15遵循相同的原则:
15 = 1111
,以及 31 = 11111
希望对您有所帮助!