I am attempting to come up with a generic function that will rotate the digits of a given number to the left or the right by n. At this point I've only been able to work out an implementation for left shift:
public static T RotateDigitsLeft<T>(this T value, int count) where T : IBinaryInteger<T> {
var absoluteValue = T.Abs(value: value);
var countAsT = T.CreateTruncating(value: count);
var digitCount = absoluteValue.LogarithmBase10();
var factor = BinaryIntegerConstants<T>.Ten.Exponentiate(exponent: (digitCount - countAsT));
var endDigits = (absoluteValue / factor);
var startDigits = (absoluteValue - (endDigits * factor));
return T.CopySign(sign: value, value: ((startDigits * BinaryIntegerConstants<T>.Ten.Exponentiate(exponent: countAsT)) + endDigits));
}
- Is it possible to alter this in a way that works for negative values of
count? - A subset of rotations result in invalid values, depending on the size of
T; is there a decent way to check for these generically so that one can throw? - Can one alter the function to support right rotation as well?
Note: Answers that continue to use arithmetic will be preferred because I find them more interesting.
Examples:
54321->43215(rotate left by 1, rotate right by 4)54321->32154(rotate left by 2, rotate right by 3)54321->21543(rotate left by 3, rotate right by 2)54321->15432(rotate right by 1, rotate left by 4)54321->21543(rotate right by 2, rotate left by 3)54321->32154(rotate right by 3, rotate left by 2)1123456789->1234567891(rotate left by 1)1123456789->EXCEPTION(rotate right by 1)
I suggest converting integer to
stringrotate it and thenParseback to integer:The only difference between
RotateDigitsRightandRotateDigitsLeftis in thecountcomputation, i.e.Fiddle
Please, note that rotation as it designed can throw exception, e.g. if we rotate
bytee.g.255by1will get552or525which is beyond0..255range.Another problem (which I've avoided) is with negative numbers: note, that
Abs(value)can be beyond range e.g.Abs(int.MinValue)can't be computed asint: