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)