I need to convert a 21 bit signed integer (provided in three 7-bit characters) into a 32 bit signed integer. I'm trying to make the function below work. If I define outval as integer, I get range check on the "outval := outval or $FFF00000" statement. If I change outval to a longword, I get range check on "Val21bit := outval". Range checks occur only when the value is negative.
Other than turning off range checking around the assignment, is there any "proper" way to make this work?
function Val21bit(sx:string):integer; {Input of 3 character string, Vh, Vm, Vl}
var
outval : longword; // define as Longword to allow or-ing in high bit
{ valueH : 0scccccc
valueM : 0bbbbbbb
valueL : 0aaaaaaa
int : ssssssss sssscccc ccbbbbbb baaaaaaa }
begin
outval := byte(sx[1]); // 00000000 00000000 00000000 0scccccc highest order first
outval := (outval shl 7) or ($7F and byte(sx[2])); // 00000000 00000000 00sccccc cbbbbbbb
outval := (outval shl 7) or ($7F and byte(sx[3])); // 00000000 000scccc ccbbbbbb baaaaaaa
if (outval and $00100000) <> 0 then // ^ if sign bit is high, fill in to left
outval := outval or $FFF00000; // ssssssss sssscccc ccbbbbbb baaaaaaa
Val21bit := outval;
end;
Yes, just typecast explicitly:
Val21bit := Integer(outval);
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