您可以选择使用旋转而不是移位。这保留了所有的位。如果您希望使用由换档产生的中间值,请执行旋转和换档。跟踪rotate返回的值,但使用shift返回的值。此问题提供了旋转操作的各种实现: Delphi中的RolDWord实现(32位和64位)?
另一种选择是永远不要修改原始值。而只是跟踪累积的转变,当需要一个值时,返回它。
type TLosslessShifter = record private FData: Cardinal; FShift: Integer; function GetValue: Cardinal; public class function New(Data: Cardinal): TLosslessShifter; static; procedure Shift(ShiftIncrement: Integer); property Value: Cardinal read GetValue; end; class function TLosslessShifter.New(Data: Cardinal): TLosslessShifter; begin Result.FData := Data; Result.FShift := 0; end; procedure TLosslessShifter.Shift(ShiftIncrement: Integer); begin inc(FShift, ShiftIncrement); end; function TLosslessShifter.GetValue: Cardinal; begin if FShift > 0 then Result := FData shr FShift else Result := FData shl -FShift; end;
一些示例用法和输出:
var Shifter: TLosslessShifter; .... Shifter := TLosslessShifter.New(8); Shifter.Shift(-1); Writeln(Shifter.Value); Shifter.Shift(5); Writeln(Shifter.Value); Shifter.Shift(-4); Writeln(Shifter.Value);
输出:
16 0 8