Byte array to Signed integer in Delphi -
source array(4 bytes)
[$80,$80,$80,$80] =integer 0 [$80,$80,$80,$81] = 1 [$80,$80,$80,$ff] = 127 [$80,$80,$81,$01] = 128
need convert integer.
below code , working @ moment.
function convert(b: array of byte): integer; var i, st, p: integer; negative: boolean; begin result := 0; st := -1; := 0 high(b) begin if b[i] = $80 continue // skip leading 80 else begin st := i; negative := b[i] < $80; b[i] := abs(b[i] - $80); break; end; end; if st = -1 exit; := st high(b) begin p := round(power(254, high(b) - i)); result := result + b[i] * p; result := result - (p div 2); end; if negative result := -1 * result end;
i'm looking better function?
update:
file link https://drive.google.com/file/d/0byba4qf-yoggzudzcxpmos1aam8/view?usp=sharing
- in uploaded file id field offset 5 9
new:
got new problem decoding date field
date field hex [$80,$8f,$21,$c1] -> possible date 1995-12-15
* in uploaded file date field offset 199 203
just example of improvements outlined david.
- the array passed reference const.
- the array fixed in size.
- the use of floating point calculations converted directly constant array.
const maxrange = 3; type tmyspecial = array[0..maxrange] of byte; function convert(const b: tmyspecial): integer; var i, j: integer; negative: boolean; const // pwr[i] = round(power(254,maxrange-i)); pwr: array[0..maxrange] of cardinal = (16387064,64516,254,1); begin := 0 maxrange begin if (b[i] <> $80) begin negative := b[i] < $80; result := abs(b[i] - $80)*pwr[i] - (pwr[i] shr 1); j := i+1 maxrange result := result + b[j]*pwr[j] - (pwr[j] shr 1); if negative result := -result; exit; end; end; result := 0; end;
note less code lines not sign of performance. measure performance before optimizing code in order find real bottlenecks. code readability better optimizing on top.
and future references, please tell algorithm supposed do.
code testing:
const x : array[0..3] of tmyspecial = (($80,$80,$80,$80), // =integer 0 ($80,$80,$80,$81), // = 1 ($80,$80,$80,$ff), // = 127 ($80,$80,$81,$01)); // = 128 var i,j: integer; sw: tstopwatch; begin sw := tstopwatch.startnew; := 1 100000000 j := 0 3 convert(x[j]); writeln(sw.elapsedmilliseconds); readln; end.
Comments
Post a Comment