Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 可以包含整数值的最小字节数_C#_Integer_Bit Manipulation - Fatal编程技术网

C# 可以包含整数值的最小字节数

C# 可以包含整数值的最小字节数,c#,integer,bit-manipulation,C#,Integer,Bit Manipulation,给定一个整数值,我需要某种方法来找出存储该值所需的最小字节数。该值可以是有符号或无符号的,最多64位。对于有符号整数,还要考虑符号位 例如: 8 requires 1 byte at minimum unsigned 255 requires 1 byte at minimum signed 255 requires 2 bytes at minimum

给定一个整数值,我需要某种方法来找出存储该值所需的最小字节数。该值可以是有符号或无符号的,最多64位。对于有符号整数,还要考虑符号位

例如:

                          8     requires 1 byte at minimum
               unsigned 255     requires 1 byte at minimum
                 signed 255     requires 2 bytes at minimum
                       4351     requires 2 bytes at minimum
                -4294967296     requires 5 bytes at minimum
unsigned 0xFFFFFFFFFFFFFFFF     requires 8 bytes at minimum
我可以想出一种快速而肮脏的方法来解决这个问题,使用许多if语句,但可能有更好的方法(例如,更简单、更聪明、更快)来解决这个问题。您可以假设一个方法具有签名
int(长值,bool签名)
,或者两个方法
int(长值)
(用于签名)和
int(ulong值)
(用于无签名)。

静态int字节数(长值,bool签名)
{
如果(值==0)
返回1;
如有(签名)
{
如果(值<0)
返回计算字节(2*(-1-值));
其他的
返回计算字节(2*值);
}
其他的
{
如果(值<0)
抛出新ArgumentException(“不能表示负无符号数”、“值”);
返回计算字节(值);
}
}
//只能用正数调用
专用静态整数计算字节(长值)
{
int位长度=0;
而(值>0)
{
位长度++;
值>>=1;
}
返回值(整数)(数学上限(位长*1.0/8));
}
我可能没有完全正确的签名代码,但这是一般的想法。

static int BytesForNum(long value,bool signed)
{
如果(值==0)
返回1;
如有(签名)
{
如果(值<0)
返回计算字节(2*(-1-值));
其他的
返回计算字节(2*值);
}
其他的
{
如果(值<0)
抛出新ArgumentException(“不能表示负无符号数”、“值”);
返回计算字节(值);
}
}
//只能用正数调用
专用静态整数计算字节(长值)
{
int位长度=0;
而(值>0)
{
位长度++;
值>>=1;
}
返回值(整数)(数学上限(位长*1.0/8));
}

我可能没有完全正确的签名代码,但这是一般的想法。

让我试一下我自己的问题。据我所知,这是一个正确的解决方案,但在速度、简洁性方面可能不是最优的:

public static int GetMinByteSize(long value, bool signed)
{
    ulong v = (ulong)value;
    // Invert the value when it is negative.
    if (signed && value < 0)
        v = ~v;
    // The minimum length is 1.
    int length = 1;
    // Is there any bit set in the upper half?
    // Move them to the lower half and try again.
    if ((v & 0xFFFFFFFF00000000) != 0)
    {
        length += 4;
        v >>= 32;
    }
    if ((v & 0xFFFF0000) != 0)
    {
        length += 2;
        v >>= 16;
    }
    if ((v & 0xFF00) != 0)
    {
        length += 1;
        v >>= 8;
    }
    // We have at most 8 bits left.
    // Is the most significant bit set (or cleared for a negative number),
    // then we need an extra byte for the sign bit.
    if (signed && (v & 0x80) != 0)
        length++;
    return length;
}
public static int GetMinByteSize(长值,布尔签名)
{
ulong v=(ulong)值;
//当值为负值时,将其反转。
if(有符号和值<0)
v=~v;
//最小长度为1。
整数长度=1;
//上半部分是否设置了位?
//将它们移到下半部分,然后重试。
如果((v&0xffffff00000000)!=0)
{
长度+=4;
v>>=32;
}
如果((v&0xFFFF0000)!=0)
{
长度+=2;
v>>=16;
}
如果((v&0xFF00)!=0)
{
长度+=1;
v>>=8;
}
//我们最多只剩下8位了。
//是最高有效位集(或为负数清除),
//然后我们需要一个额外的字节作为符号位。
如果(已签名和(v&0x80)!=0)
长度++;
返回长度;
}

让我试一下我自己的问题。据我所知,这是一个正确的解决方案,但在速度、简洁性方面可能不是最优的:

public static int GetMinByteSize(long value, bool signed)
{
    ulong v = (ulong)value;
    // Invert the value when it is negative.
    if (signed && value < 0)
        v = ~v;
    // The minimum length is 1.
    int length = 1;
    // Is there any bit set in the upper half?
    // Move them to the lower half and try again.
    if ((v & 0xFFFFFFFF00000000) != 0)
    {
        length += 4;
        v >>= 32;
    }
    if ((v & 0xFFFF0000) != 0)
    {
        length += 2;
        v >>= 16;
    }
    if ((v & 0xFF00) != 0)
    {
        length += 1;
        v >>= 8;
    }
    // We have at most 8 bits left.
    // Is the most significant bit set (or cleared for a negative number),
    // then we need an extra byte for the sign bit.
    if (signed && (v & 0x80) != 0)
        length++;
    return length;
}
public static int GetMinByteSize(长值,布尔签名)
{
ulong v=(ulong)值;
//当值为负值时,将其反转。
if(有符号和值<0)
v=~v;
//最小长度为1。
整数长度=1;
//上半部分是否设置了位?
//将它们移到下半部分,然后重试。
如果((v&0xffffff00000000)!=0)
{
长度+=4;
v>>=32;
}
如果((v&0xFFFF0000)!=0)
{
长度+=2;
v>>=16;
}
如果((v&0xFF00)!=0)
{
长度+=1;
v>>=8;
}
//我们最多只剩下8位了。
//是最高有效位集(或为负数清除),
//然后我们需要一个额外的字节作为符号位。
如果(已签名和(v&0x80)!=0)
长度++;
返回长度;
}

您需要两个输入(long val,bool signed),对吗?正确,
(long value,bool signed)
将满足它被签名或未签名的要求,最多64位。但它也可能有两种方法,一种是
(长值)
另一种是
(ulong值)
。您需要两个输入(长值,bool签名),对吗?正确,
(长值,bool签名)
将满足它被签名或未签名的要求,最多64位。但是它也可能有两种方法,一种是
(long value)
另一种是
(ulong value)
。因此,如果我传递值((long),false),那么我会得到一个异常?如果你试图在
未选中的
上下文之外执行此操作,你会得到一个编译错误。但这带来了一个好的观点:如果
value
大于大约
long.MaxValue/2
并且
签名的
true
,我的代码将失败。一个简单的if可以解决这个问题。那
CalcBytes
函数真的保存了吗?
Math.Log
是否保证足够准确?很好。我将其替换为使用位移位的代码。这应该是非常准确的。您的代码不能处理我帖子中的所有情况(更准确地说,任何大于
Int64.MaxValue
的数字在签名时都是
false
),并且对于至少
0x80000000000000
0xffffffffffffff
(-1)是不正确的当它返回值0时,带符号的
0x7FFFFFFFFFFFFFFF
,这显然是错误的。
-1-x
是否与
~x
相同?因此,如果我传递值((长),false),那么我会得到一个异常?如果您尝试在未选中的
上下文之外执行此操作,您将得到一个编译错误。但这带来了一个好的观点:如果
value
大于大约
long.MaxValue/2
并且
签名的
true
,我的代码将失败。一个简单的if可以解决这个问题。那是