C# 不带递归的int到二进制函数?
我想把十进制数显示为位C# 不带递归的int到二进制函数?,c#,bit-manipulation,C#,Bit Manipulation,我想把十进制数显示为位 int g = 2323; for (int i = 31; i>=0; i--) // int has 32 bits { Console.Write(((g >> 1) & 1) == 1 ? "1" : "0"); // shift right 1 and display it g = g / 2; // shift right= divide by 2 } 但是,这会像镜像一样显示数字(12345->54321) 我可
int g = 2323;
for (int i = 31; i>=0; i--) // int has 32 bits
{
Console.Write(((g >> 1) & 1) == 1 ? "1" : "0"); // shift right 1 and display it
g = g / 2; // shift right= divide by 2
}
但是,这会像镜像一样显示数字(12345->54321)
我可以从左向左移动,但是:我可能会出现异常..(数字太大)
我需要在代码中更改什么才能正确显示,但:
有什么吗?移动一个面具,而不是移动数字。从0x80000000开始,并使用编号(&T)。非零结果='1'。将遮罩向右移动31次以检查所有位位置 移动遮罩,而不是移动数字。从0x80000000开始,并使用编号(&T)。非零结果='1'。将遮罩向右移动31次以检查所有位位置 就在我的头顶上:
int g = 2323;
for (uint mask = 0x80000000; mask != 0; mask >>= 1)
Console.Write(((uint)g & mask) != 0 ? "1" : "0");
就在我的头顶上:
int g = 2323;
for (uint mask = 0x80000000; mask != 0; mask >>= 1)
Console.Write(((uint)g & mask) != 0 ? "1" : "0");
您将从左向右,因此它们将从左向右打印:) 您可以创建一个MSB为1的掩码,并在每次迭代时将其右移1位(不要忘记使掩码
无符号)
可以通过将1向左移动32位来创建掩码,如
unsigned int mask = 1 << 32;
此循环类似于代码中的循环。您将从左向右,因此它们将从左向右打印:)
您可以创建一个MSB为1的掩码,并在每次迭代时将其右移1位(不要忘记使掩码无符号)
可以通过将1向左移动32位来创建掩码,如
unsigned int mask = 1 << 32;
此循环与代码中的循环类似。您可以使用LINQ简化代码
string.Join("", Enumerable.Range(0, 32).Select(i => (num >> (31 - i) & 1).ToString()))
您可以使用LINQ简化代码
string.Join("", Enumerable.Range(0, 32).Select(i => (num >> (31 - i) & 1).ToString()))
此解决方案与您的解决方案类似,但它检查最高有效位(由0x80000000
屏蔽,对应于二进制中的100000000000000000000000000000
),而不是最低有效位(由1
屏蔽)
uint g=2323;
对于(int i=0;i<32;++i)
{
控制台写入((g&0x8000000)==0?“0”:“1”);
g此解决方案与您的解决方案类似,但它检查最高有效位(由0x80000000
屏蔽,对应于二进制中的100000000000000000000000000000
),而不是最低有效位(由1
屏蔽)
uint g=2323;
对于(int i=0;i<32;++i)
{
控制台写入((g&0x8000000)==0?“0”:“1”);
g为什么前两个约束是必要的或实际上是合理的?转换:我想自己做位运算。中间人:不是很聪明+性价比。为什么没有转换方法(例如,var binary=Convert.ToString(2323,2);)。这将是最简单和干净的方法?为什么?Console.Write(Convert.ToString(g,2))…那么为什么要使用所有其他约束?调用控制台时。为每一位写入行,而不是在stringbuilder中对结果进行重击,然后将结果反向写入。这有点过早优化的味道。前两个约束为什么是必要的或实际上是合理的?转换:我想自己做位操作。中间人:不太聪明+性价比。为什么没有转换方法(例如,var binary=convert.ToString(2323,2);)。这将是最简单、最干净的方法?为什么?Console.Write(convert.ToString(g,2))…为什么还有其他的限制?调用控制台时。每一位都写一行,而不是在stringbuilder中对结果进行重击,然后将结果反向写入。这有点过早优化的味道,示例?(示例的和平)@RoyiNamir:他为什么要写你的代码?描述很清楚,示例?(示例的和平)@罗伊纳米尔:他为什么要写你的代码?描述已经很清楚了。LINQ的使用很酷,但它似乎违反了约束的精神#2(没有中间人数组)。您正在创建多个单字符字符串,然后将它们合并形成最终字符串。错误2参数2:无法从“System.Collections.Generic.IEnumerable”转换为“string[]”@RoyiNamir:您使用的是.NET的哪个版本?代码通过了.NET 4上的测试。如果您使用的是较低版本,请添加.ToArray()
到.ToString())
的末尾将消除错误。LINQ的使用很酷,但它似乎违反了约束的精神#2(无中间人数组)。您正在创建多个单字符字符串,然后将它们合并形成最终字符串。错误2参数2:无法从“System.Collections.Generic.IEnumerable”转换为“string[]”@RoyiNamir:您使用的是.NET的哪个版本?代码通过了.NET 4上的测试。如果您使用的是较低版本,请添加.ToArray()
到.ToString())
将消除错误。这是因为0x8000000=2147483648,即(int.max+1)?我之所以使用它,是因为在二进制中它是一个1后跟31个0。对不起,我误解了你的问题。我使用了uint,以便>=运算符执行逻辑右移(无符号扩展)不是算术右移。是因为0x8000000=2147483648,即(int.max+1)?我之所以使用它,是因为在二进制中,它是一个后跟31个零的1。对不起,我误解了你的问题。我使用了uint,以便>>=运算符执行逻辑右移(无符号扩展)而不是算术右移。
uint g = 2323;
bool isSignificant = false;
for (int i = 0; i < 32; ++i)
{
bool isZero = (g & 0x80000000) == 0;
if (!isZero)
isSignificant = true;
if (isSignificant)
Console.Write(isZero ? "0" : "1");
g <<= 1;
}