How do I omit the leading 0 from a 128C bar code? - delphi

If I put 12345, for example, in a "text" bar code's property, the output is 012345.
This "0" is the problem. How I can remove this?
I'm using Delphi 2010 and FastReport 4.9.72.

A Code 128C barcode needs to be an even number of digits. This is by design.
There is a 1:1 mapping between the numbers and the resulting output, and the output is 2-digit aligned. In the case of 1 the Code 128C representation of this number is 01
if the value was 12 then the underlying representation would be 12
so the digits 628 can only be represented by 0628
The wikipedia article about Code 128 explains the differences between the 128A, 128B and 128C encodings.

To remove leading zeros from a string:
function RemoveLeadingZeros(const S: String): String;
var
I, NumZeros: Integer;
begin
Len := 0;
for I := 1 to Length(S) do
begin
if S[I] <> '0' then Break;
Inc(NumZeros);
end;
if NumZeros > 0 then
Result := Copy(S, NumZeros+1, MaxInt)
else
Result := S:
end;

Related

Delphi Even Odd Problems

Having a problem whenever i want when typing in 2 4 6 8 10 etc i want to have the answer to come out as Even but cant seem to to find the solutioin
if (Edit1.Text = '2' ) then
Edit2.Text := 'Even'
else
Edit2.Text := 'Odd'
Tryed to divide 2 but it always fails.
Convert the text to an integer and use the Odd function:
if Odd(StrToInt(Text)) then
// the value is odd
You need to first convert the text in the textbox to a numeric type like Integer, and then compare that value by modulus of 2 (the remainder of integer division):
var
value: Integer;
begin
...
value := StrToInt(Edit1.Text);
if ((value mod 2) = 0) then
Edit2.Text := 'Even'
else
Edit2.Text := 'Odd';
...
end;
There is nice and short explanation on mod operator here:
FreePascal Wiki on Mod:
mod (modulus) divides two numbers and returns only the remainder that
is a whole number. For instance, the expression a:= 13 mod 4; would
evaluate to 1 (a=1), while b := 12 mod 4; would evaluate to 0 (b=0).

Reading bit by bit out of bytes - simplification/speed-up suggestions - Delphi

I have a device that sends couple bytes of info about its status, and the first 5 bytes are statuses of 40 pushbuttons. Each bit represents one button, being 1 for released and 0 for pressed.
From that matter, I was doing a checkout using this piece of code:
procedure TForm2.ServerUDPRead(AThread: TIdUDPListenerThread;
AData: array of Byte; ABinding: TIdSocketHandle);
var received: array [0..4] of string; a1, a2 integer;
bits: array [0..40] of boolean;
begin
for a1 := 0 to 4 do
Received[a1] := (ByteToBin(AData[a1]));
for a1 := 4 downto 0 do
begin
for a2 := 1 to 8 do
begin
if Copy(Received[a1], a2, 1) = '0' then bits[(4-a1)*8+(a2-1)]:=False else bits[(4-a1)*8+(a2-1)]:=True;
end;
end;
ByteToBin being function for coverting byte to string of 8 bits...
Is there an alternate "easier", simplified and (what I'm actually interested in) faster procedure for achieving what I need, or is this way good enough?
I find it a bit sluggish and dirty... :/ (although ultimately, does it's intention... so interested mostly out of learning point of view)
With this you an convert directly from AData to array of boolean:
for i := 0 to 39 do
bits[i] := (AData[i div 8] and (1 shl (i mod 8))) <> 0;
I'm not sure if the order of the booleans is exactly the same, I lost count with all your indexes :)
An alternative approach is using a set:
type
TByteSet = set of 0..7;
...
for I := 0 to 39 do begin
bits[I] := (I mod 8) in TByteSet(AData[I div 8]);
end;

Convert an Octal number to Decimal and Hexadecimal

I am writing a program that converts an Octal number to Decimal and Hexadecimal. I wrote a function called OctToInt.
function OctToInt(Value: string): Longint;
var
i: Integer;
int: Integer;
begin
int := 0;
for i := 0 to Length(Value) do
begin
int := int * 8 + StrToInt(Copy(Value, i, 1));
end;
Result := int;
end;
I call this function in this way:
var oct:integer;
begin
oct:=OctToInt(Edit13.Text);
Edit15.Text:=IntToStr(oct);
end;
When I type 34 (Octal) the decimal number should be 28 but the program gives me 220. Do you know why?
Also, do you have any idea about a converter OctToHex?
You have to change the start of "your" for with 1.
function OctToInt(Value: string): Longint;
var
i: Integer;
int: Integer;
begin
int := 0;
for i := 1 to Length(Value) do //here you need 1, not 0
begin
int := int * 8 + StrToInt(Copy(Value, i, 1));
end;
Result := int;
end;
The conversion Octal-Hexadecimal could be hard to do, so I suggest you another way:
EditHexadecimal.Text:=(IntToHex(StrToInt(EditInteger.Text),8));
As you can see here, with this code the EditHexadecimal is the Edit where you put the hexadecimal number. With that line I convert a number from decimal to hexadecimal.
You already have the decimal number because you get it with the function OctToInt, so you don't need more code.
This code accepts a string with a base-8 representation of an integer, and returns the corresponding integer:
function IntPower(const N, k: integer): integer;
var
i: Integer;
begin
result := 1;
for i := 1 to k do
result := result * N;
end;
function OctToInt(const Value: string): integer;
var
i: integer;
begin
result := 0;
for i := 1 to Length(Value) do
inc(result, StrToInt(Value[i]) * IntPower(8, Length(Value) - i));
end;
When it comes to converting an integer to a hexadecimal string representation, you already have IntToHex.
i made this formula so you can process octals in batches of 3-digits at a time - it's been tested from 000 through 777 to perfectly generate the decimal integer from octals :
if your octals are in a variable oct and temp placeholder o2
then
(37 < oct % 100)*8 + int(0.08*(oct-(o2=oct%10))+0.7017)*8 + o2
if you wanna further streamline that without the placeholder, then its
(37 < oct%100)*8 + int(0.7017+0.08*(oct-(oct%=10)))*8 + oct
the "0.7017" is possibly sin(-10*π/8) or 1/sqrt(2), or just 2^(1/-2), but since i found the formula via regression i'm not 100% sure on this.
Another fast trick is that if all 3 digits are the same number - 222 333 555 etc, simply take the first digit then multiply by 73 (cuz 73 in octal is 111). The sequence chain of multipliers for 2-6 consecutive matching digits are
9, 73, 585, 4681, 37449
(it also happens that within this list, for each x,
one of {x-2,x+0,x+2} is prime

Converting 20-digit decimal value to Hexadecimal using delphi code

I am trying to convert 20 digit decimal value to hexadecimal using Delphi code. Although I find the code below in C#.
BigInteger bi = new BigInteger("12345678901234567890");
string s = bi.ToHexString();
Can anyone help with equivalent delphi code to achieve this objective?
Please note that using kstools code, I was able to convert 17 digit hexadecimal value to 20 digit decimal but I cannot reverse it to get back the hexadecimal value.
The kstool code is as follows:
var
I: TksInteger;
....
I.FromString('$ABDCF123456789FE');
Result = I.AsString;
Here's a Delphi translation of a C# answer to an identical question:
program DecToHex;
{$APPTYPE CONSOLE}
uses
SysUtils, Generics.Collections;
function DecimalToHex(const Dec: string): string;
var
bytes: Generics.Collections.TList<Byte>;
i, digit, val: Integer;
b: Byte;
c: Char;
begin
bytes := Generics.Collections.TList<Byte>.Create;
try
bytes.Add(0);
for c in Dec do
begin
Assert(CharInSet(c, ['0'..'9']));
val := ord(c)-ord('0');
for i := 0 to bytes.Count-1 do
begin
digit := bytes[i]*10 + val;
bytes[i] := digit and $0F;
val := digit shr 4;
end;
if (val<>0) then
bytes.Add(val);
end;
Result := '';
for b in bytes do
Result := '0123456789ABCDEF'[b+1] + Result;
finally
bytes.Free;
end;
end;
const
test = '56493153725735501823';
begin
WriteLn(test + ' = $' + DecimalToHex(test));
end.
Output:
56493153725735501823 = $30FFFFFFFFFFFFFFF
What's the problem exactly?
Using the example that you've given, it just works here.
Proof
This code converts 12345678901234567890 to a string, and then back to a number.
program Project122; {$APPTYPE CONSOLE}
uses SysUtils;
const SomeBigNumber=12345678901234567890;
var S:String; SomeBigNumber2:UInt64;
begin
WriteLn(SomeBigNumber);
S := '$'+IntToHex(SomeBigNumber, 40);
Writeln('As Hex: ',S);
Writeln;
Writeln('Now let''s convert it back...');
SomeBigNumber2 := StrToInt64(S);
Writeln(SomeBigNumber2);
ReadLn;
end.
output:
12345678901234567890 As Hex:
$AB54A98CEB1F0AD2
Now let's convert it back...
12345678901234567890
If you want to convert any 20-digit number, this won't work, because the largest ones don't fit in a UINT64.
18446744073709551615 is the largest number that you can fit in a UIN64.
12345678901234567890
The same as David Heffernan translation but optimized and compatible with older Delphi versions...
function DecimalToHex(const Dec: AnsiString): AnsiString;
var
ResultArray: array of byte;
n, i: Integer;
val, digit: Byte;
c: AnsiChar;
begin
SetLength(ResultArray, Trunc(Length(Dec) * Ln(10) / Ln(16)) + 1);
n := 0;
for c in Dec do
begin
Assert(CharInSet(c, ['0'..'9']));
val := ord(c) - ord('0');
for i := 0 to n do
begin
digit := ResultArray[i] * 10 + val;
ResultArray[i] := digit and $0F;
val := digit shr 4;
end;
if val <> 0 then
begin
inc(n);
ResultArray[n] := val;
end;
end;
Result := '';
for digit in ResultArray do
Result := AnsiString('0123456789ABCDEF')[digit + 1] + Result;
end;
The following Delphi function converts a decimal number and returns a right-justified hexadecimal number. It is not elegant, but it works.
//Uses STRUTILS Delphi module
function IHEX(x:Double): string; //Returns hex number as right-justified string
var i,k,a,mx:Integer;
y,Z,a1:currency;
s:string;
hxs: array[0..15] of string;
const hx='0123456789ABCDEF';
begin
Y:=abs(X); //Make sure target decimal is not a negative number
mx:=0; //Count number of hex digits derived from conversion
repeat
z:= y / 16; // Divide the decimal number by base 16
a:=Trunc(z); // Get integer part of dividend
if z>=16 then begin //If integer dividend greater than 16
a1:=16 * Frac(z);//Get the dividend carry-over
k:=Trunc(a1); // Base 16 left-to-right placement digit
If k<=9 then hxs[mx]:=IntToStr(k) //if hex digit greater than 9,
else
hxs[mx]:=hx[k+1]; //get hex alpha digit
mx:=mx+1; //increment hex digit placement
y:=a; //Replace decimal with current dividend result
end;
if z<16 then begin //When dividend less than 16,
a1:=16 * Frac(z); //get dividend carry-over
k:=Trunc(a1); //Base 16 left-to-right placement digit
If k<=9 then hxs[mx]:=IntToStr(k) //If hex digit greater than 9,
else
hxs[mx]:=hx[k+1]; //get hex alpha digit
mx:=mx+1; //increment hex digit placement
y:=a; //Replace decimal with current dividend result
end;
until y<16; //When loop ends, last hex digit derived from division
If a<=9 then hxs[mx]:=IntToStr(a) //If last hex digit greater than 9,
else
hxs[mx]:=hx[a+1]; //get hex alpha digit
//Pull HEX digits from placement array in reverse order to create HEX number
s:='';
i:=mx;
repeat
s:=s + hxs[i];
i:=i-1;
until i<0;
s:=s+'H';
//Format HEX number as seven characters RIGHT-JUSTIFIED
repeat
k:=Length(s);
if k<7 then s:='0'+s;
until Length(s)>=7;
Result:=s;
end;

How to keep 2 decimal places in Delphi?

I have selected columns from a database table and want this data with two decimal places only. I have:
SQL.Strings = ('select '#9'my_index '#9'his_index,'...
What is that #9?
How can I deal with the data I selected to make it only keep two decimal places?
I am very new to Delphi.
#9 is the character with code 9, TAB.
If you want to convert a floating point value to a string with 2 decimal places you use one of the formatting functions, e.g. Format():
var
d: Double;
s: string;
...
d := Sqrt(2.0);
s := Format('%.2f', [d]);
function Round2(aValue:double):double;
begin
Round2:=Round(aValue*100)/100;
end;
#9 is the tab character.
If f is a floating-point variable, you can do FormatFloat('#.##', f) to obtain a string representation of f with no more than 2 decimals.
For N Places behind the seperator use
function round_n(f:double; n:nativeint):double;
var i,m : nativeint;
begin
m := 10;
for i := 1 to pred(n) do
m := m * 10;
f := f * m;
f := round(f);
result := f / m;
end;
For Float to Float (with 2 decimal places, say) rounding check this from documentation. Gives sufficient examples too. It uses banker's rounding.
x := RoundTo(1.235, -2); //gives 1.24
Note that there is a difference between simply truncating to two decimal places (like in Format()), rounding to integer, and rounding to float.
Nowadays the SysUtils unit contains the solution:
System.SysUtils.FloatToStrF( singleValue, 7, ffFixed, 2 );
System.SysUtils.FloatToStrF( doubleValue, 15, ffFixed, 2 );
You can pass +1 TFormatSettings parameter if the requiered decimal/thousand separator differ from the current system locale settings.
The internal float format routines only work with simple numbers > 1
You need to do something more complicated for a general purpose decimal place limiter that works correctly on both fixed point and values < 1 with scientific notation.
I use this routine
function TForm1.Flt2str(Avalue:double; ADigits:integer):string;
var v:double; p:integer; e:string;
begin
if abs(Avalue)<1 then
begin
result:=floatTostr(Avalue);
p:=pos('E',result);
if p>0 then
begin
e:=copy(result,p,length(result));
setlength(result,p-1);
v:=RoundTo(StrToFloat(result),-Adigits);
result:=FloatToStr(v)+e;
end else
result:=FloatToStr(RoundTo(Avalue,-Adigits));
end
else
result:=FloatToStr(RoundTo(Avalue,-Adigits));
end;
So, with digits=2, 1.2349 rounds to 1.23 and 1.2349E-17 rounds to 1.23E-17
This worked for me :
Function RoundingUserDefineDecaimalPart(FloatNum: Double; NoOfDecPart: integer): Double;
Var
ls_FloatNumber: String;
Begin
ls_FloatNumber := FloatToStr(FloatNum);
IF Pos('.', ls_FloatNumber) > 0 Then
Result := StrToFloat
(copy(ls_FloatNumber, 1, Pos('.', ls_FloatNumber) - 1) + '.' + copy
(ls_FloatNumber, Pos('.', ls_FloatNumber) + 1, NoOfDecPart))
Else
Result := FloatNum;
End;
Function RealFormat(FloatNum: Double): string;
Var
ls_FloatNumber: String;
Begin
ls_FloatNumber:=StringReplace(FloatToStr(FloatNum),',','.',[rfReplaceAll]);
IF Pos('.', ls_FloatNumber) > 0 Then
Result :=
(copy(ls_FloatNumber, 1, Pos('.', ls_FloatNumber) - 1) + '.' + copy
(ls_FloatNumber, Pos('.', ls_FloatNumber) + 1, 2))
Else
Result := FloatToStr(FloatNum);
End;

Resources