Members,
What I am trying to do is to right or left shift the digits of an Int32
(not the bits!!).
So if shift the constant:
123456789
by 3
I should get
789123456
So no digits get lost, because we talk about a circular shift. After a bit of testing I've come up with this method, which works:
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;
}
}
The way I am looking for should be an arithmetic solution, not a string conversion and then the rotation. I also assume that:
My algorithm already does all of that, and I like to know if there are way to tweak it a bit, if there is a better arithmetic solution to the problem?
Given three variables x, y, z write a function to circularly shift their values to right. In other words if x = 5, y = 8, z = 10, after circular shift y = 5, z = 8, x = 10. Call the function with variables a, b, c to circularly shift values.
Bit Rotation: A rotation (or circular shift) is an operation similar to shift except that the bits that fall off at one end are put back to the other end. In left rotation, the bits that fall off at left end are put back at right end. In right rotation, the bits that fall off at right end are put back at left end.
In computer programming, a bitwise rotation, also known as a circular shift, is a bitwise operation that shifts all bits of its operand. Unlike an arithmetic shift, a circular shift does not preserve a number's sign bit or distinguish a floating-point number's exponent from its significand.
Because I just can't resist a 'has to have an arithmetic approach' challenge :D , fiddled around with the following:
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;
}
edit Also some test results
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With