C# 使用C实现32位循环移位#

C# 使用C实现32位循环移位#,c#,int32,C#,Int32,各位委员: 我想做的是将Int32的数字右移或左移(不是位!!) 因此,如果移动常数: 123456789 按3 我应该 789123456 所以没有数字丢失,因为我们讨论的是循环移位。 经过一点测试,我想出了这个方法,它可以工作: static uint[] Pow10 = new uint[] { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, uint.MaxValue }; static uint

各位委员:

我想做的是将
Int32
的数字右移或左移(不是位!!)

因此,如果移动常数:

123456789
3

我应该

789123456
所以没有数字丢失,因为我们讨论的是循环移位。 经过一点测试,我想出了这个方法,它可以工作:

static uint[] Pow10 = new uint[] { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, uint.MaxValue };
    static uint RotateShift10(uint value, int shift)
    {
        int r = (int)Math.Floor(Math.Log10(value) + 1);
        while (r < shift)
            shift = shift - r;
        if (shift < 0) shift = 9 + shift;
        uint x = value / Pow10[shift];
        uint i = 0;
        while (true)
        {
            if (x < Pow10[i])
                return x + (value % Pow10[shift]) * Pow10[i];
            i += 1;
        }
    }
static uint[]Pow10=新uint[]{1,10,100,1000,10000,100000,1000000,10000000,uint.MaxValue};
静态单位旋转移位10(单位值、单位移位)
{
intr=(int)数学地板(数学Log10(值)+1);
while(r
我要寻找的方法应该是一个算术解决方案,而不是字符串转换和旋转。 我还假设:

  • Int32值中没有0位,以防止任何数字丢失
  • Int32是一个非负数
  • 正旋转整数应向右移动,负旋转整数应向左移动

我的算法已经完成了所有这些,我想知道是否有办法稍微调整一下,是否有更好的算法解决这个问题?

因为我无法抵抗“必须有一个算术方法”的挑战:D,摆弄以下内容:

    static uint RotateShift(uint value, int shift)
    {
        int len = (int)Math.Log10(value) + 1;
        shift %= len;
        if (shift < 0) shift += len;            
        uint pow = (uint)Math.Pow(10, shift);
        return (value % pow) * (uint)Math.Pow(10, len - shift) + value / pow;
    }

并不是所有的数字都可以这样旋转(考虑1173741829向右旋转1个位置,90亿对于整数来说太大了),那么它们呢?我们应该假设不会发生吗?@harold:是的,我假设不会发生这样的溢出,因为输入会更小;)@如果你的方法为
shift
=0抛出的值变暗,也可以使用uint.MaxValue进行尝试,它将给出一个无效的答案。哇,太酷了!我只是想找到一个解决方案,当移位为负数时,如何处理大于数字长度的移位,但您的解决方案处理得很好,并且不会产生0,其中没有:)@Me.Name它看起来令人印象深刻,不幸的是它不适用于
uint.MaxValue
;您应该使用并返回
long
值类型进行计算,以避免溢出问题。@Dzienny感谢您的评论。对于大多数移位,uint.MaxValue确实会失败,因为结果不适合uint,但是OP声明输入将更小,返回值基于原始方法签名。尽管如此,对于那些想要一个没有警告的函数的人来说,这仍然是一个有效点:将所有uint更改为ulongs,包括返回值(但不更改输入值),确实可以做到这一点。@DarkSide很高兴你能使用它:)负移位大于长度的秘密是在将移位更改为之前对长度进行模运算(长度移位)
foreach(var val in new uint[]{123456789, 12345678})
   foreach (var shift in new[] { 3, -3, 1, -1, 11, -11, 18 })
   {
      Console.WriteLine("Value {0} Shift {1} -> {2}", val, shift, RotateShift(val, shift));
   }

Value 123456789 Shift 3 -> 789123456
Value 123456789 Shift -3 -> 456789123
Value 123456789 Shift 1 -> 912345678
Value 123456789 Shift -1 -> 234567891
Value 123456789 Shift 11 -> 891234567
Value 123456789 Shift -11 -> 345678912
Value 123456789 Shift 18 -> 123456789
Value 12345678 Shift 3 -> 67812345
Value 12345678 Shift -3 -> 45678123
Value 12345678 Shift 1 -> 81234567
Value 12345678 Shift -1 -> 23456781
Value 12345678 Shift 11 -> 67812345
Value 12345678 Shift -11 -> 45678123
Value 12345678 Shift 18 -> 78123456