1
2 // Since this is Assembly Language code for Delphi, you need
3 // a version (such as Enterprise) that supports compiling it.
4
5 // NOTE: ByteBool, WordBool, and LongBool should be typecast
6 // to Boolean when calling this function
7 // Example: IntegerValue := B2I(Boolean(WB)); (cast of WordBool type)
8
9
10 // convert True or False to guaranteed 1 or 0
11 function B2I(b: Boolean): Integer;
12 // This block is how you might ordinarily do this in Delphi,
13 // especially if you don't have a version that supports Assembly:
14 //begin // recall that numerically, any nonzero value is True
15 // Result := ORD(b <> False);
16 //end;
17 // But: the above code compiles to 8 bytes...
18
19
20 //Efficient Assembly Code (6 bytes):
21 // When the B2I() function begins, the Boolean value
22 // from parameter b is in Register al
23 // and a zero is False; any other value can be True
24 asm
25 neg al
26 // negation of any nonzero value will set the Carry Flag
27 sbb eax, eax
28 // subtraction of itself (with borrow) yields 0 (or -1 if Carry set)
29 neg eax
30 // negation now yields only one nonzero value (-1 becomes 1)
31 end;
32 // When this funcion ends, Register eax holds the Result value
33
34 //NOTE: this function was developed because InterBase does
35 // not support Boolean data. So, in converting a Paradox
36 // database to InterBase, it is convenient for existing boolean
37 // variables to remain the same, so long as when passed to the
38 // database, they are converted using B2I(). Note that converting
39 // them from 0 or 1 to true or false, when pulling the data back
40 // from InterBase integer form, is almost trivially easy:
41
42 //BoolVar := (FieldByName('IntField').AsInteger <> 0);
43
44 //Final note: for long-term portability, it is always best to
45 // compare a boolean value with False instead of True.
46 // That is:
47 // if (BoolVar = False) then
48 // or
49 // if (BoolVar <> False) then
50 // is better than
51 // if (BoolVar = True) then
52 // or
53 // if (BoolVar <> True)
54 //The reason is because False is always exactly one value: zero
55 // while True may be any nonzero value in Delphi. In porting a
56 // comparison of True, you cannot be certain that the ported
57 // comparison will work properly (True may have a particular
58 // value in the destination environment).
|