【问题标题】:Replace byte in a int替换 int 中的字节
【发布时间】:2012-10-31 15:21:32
【问题描述】:

一个int由4个字节组成。我怎么能用新字节替换这 4 个字节之一。换句话说,我正在寻找一种方法:

int ReplaceByte(int index, int value, byte replaceByte)
{
     // implementation
}

例如,如果我有值 FFFFFFFF (-1) 并且我想用 0 替换字节 0A (10),那么我将调用该方法:

ReplaceByte(0,-1,10)

我会喜欢这种方法来返回我FFFFFF0A

我是否必须将 int 转换为字节数组,然后替换我想要的字节,然后再转换回 int?我正在寻找一种有效的方法来做到这一点。我们正在创建一个类似于调试器的程序,它连接到一个目标(板),我们非常频繁地更新这些值。

编辑(结果)

感谢您的回答,我比较了这些方法:

结果如下:

注意我的实现是最慢的!

代码如下:

    static void Main ( string[ ] args )
    {
        byte[ ] randomBytes = new byte[ 1024 * 1024 * 512 ]; 

        Random r = new Random( );
        r.NextBytes( randomBytes );

        Int64 sum;
        var now = DateTime.Now;

        Console.WriteLine( "Test 1" );
        sum = 0;
        now = DateTime.Now;
        foreach ( var bt in randomBytes )
        {
            sum += ReplaceByte1( 1 , -1 , bt );
        }

        Console.WriteLine( "Test 1 finished in {0} seconds \t hash = {1} \n" , ( DateTime.Now - now ).TotalSeconds, sum );

        Console.WriteLine( "Test 2" );
        sum = 0;
        now = DateTime.Now;
        foreach ( var bt in randomBytes )
        {
            sum += ReplaceByte2( 1 , -1 , bt );
        }

        Console.WriteLine( "Test 2 finished in {0} seconds \t hash = {1} \n" , ( DateTime.Now - now ).TotalSeconds,  sum );


        Console.WriteLine( "Test 3" );
        sum = 0;
        now = DateTime.Now;
        foreach ( var bt in randomBytes )
        {
            sum += ReplaceByte3( 1 , -1 , bt );
        }

        Console.WriteLine( "Test 3 finished in {0} seconds \t hash = {1} \n" , ( DateTime.Now - now ).TotalSeconds , sum );

        Console.Read( );            
    }

    // test 1
    static int ReplaceByte1 ( int index , int value , byte replaceByte )
    {
        return ( value & ~( 0xFF << ( index * 8 ) ) ) | ( replaceByte << ( index * 8 ) );
    }

    // test 2
    static int ReplaceByte2 ( int index , int value , byte replaceByte )
    {
        // how many bits you should shift replaceByte to bring it "in position"
        var shiftBits = 8 * index;

        // bitwise AND this with value to clear the bits that should become replaceByte
        var mask = ~( 0xff << shiftBits );

        // clear those bits and then set them to whatever replaceByte is
        return value & mask | ( replaceByte << shiftBits );
    }

    // test 3
    static int ReplaceByte3 ( int index , int value , byte replaceByte )
    {
        var bytes = BitConverter.GetBytes( value );
        bytes[ index ] = replaceByte;

        return BitConverter.ToInt32( bytes , 0 );
    }

【问题讨论】:

  • 奇怪,我没想到我和 Jon 的代码在性能上会有这么大的差异。您能否尝试使用 Stopwatch 类并在进入定时循环之前 至少使用一次方法,而不是在同一个数组上多次使用巨大的数组循环?

标签: c# bit-manipulation


【解决方案1】:

不,没有字节数组。这其实很简单。

未测试:

int ReplaceByte(int index, int value, byte replaceByte)
{
    return (value & ~(0xFF << (index * 8))) | (replaceByte << (index * 8));
}

首先它清除指定索引处的空间,然后将新值放入该空间。

【讨论】:

    【解决方案2】:

    您可以简单地使用一些按位算术:

    // how many bits you should shift replaceByte to bring it "in position"
    var shiftBits = 8 * index;
    
    // bitwise AND this with value to clear the bits that should become replaceByte
    var mask = ~(0xff << shiftBits);
    
    // clear those bits and then set them to whatever replaceByte is
    return value & mask | (replaceByte << shiftBits);
    

    【讨论】:

    • 好的,但为什么是var 而不是int?它甚至没有保存任何字母。
    • @harold:只是习惯。现在我几乎从不按名称声明具体类型。
    猜你喜欢
    • 2011-04-08
    • 2011-07-05
    • 2017-12-07
    • 1970-01-01
    • 2021-09-14
    • 1970-01-01
    • 1970-01-01
    • 2016-03-04
    • 2016-02-20
    相关资源
    最近更新 更多