for saving numbers to a database I use an own datatype "Triple",
which is a record of one word and one byte.
type Triple = Record Lo:Word; Hi:Byte; end;
Function Triple_To_LongInt (T:Triple): LongInt;
begin
With T do Triple_To_Longint:= Lo + (LongInt(Hi) shl 16)
end;
procedure LongInt_To_Triple (L:LongInt; var T:Triple);
begin
With T do begin Lo:=L and $ffff; Hi:=L shr 16 end;
end;
I never had a problem to convert a triple to a longint and the function
has been
very often.
Suddenly one of my users had the problem that few of the saved
numbers changed during converting.
1177 became 360211, 410 became 121149...
The program is compiled with Borland-Pascal for DOS, so there should not
be a problem with adressing the data record.
Number Hi Byte Word Hi Word Lo
-------------------------------------------
1177 0000 0000 0000 0100 1001 1001 correct
360211 0000 0101 0111 1111 0001 0011 changed
-------------------------------------------
410 0000 0000 0000 0001 1001 1010 correct
121149 0000 0001 1101 1001 0011 1101 changed
-------------------------------------------
1106 0000 0000 0000 0100 0101 0010 correct
97542 0000 0001 0111 1101 0000 0110 changed
-------------------------------------------
1085 0000 0000 0000 0100 0011 1101 correct
92580 0000 0001 0110 1001 1010 0100 changed
-------------------------------------------
345 0000 0000 0000 0001 0101 1001 correct
33340 0000 0000 1000 0010 0011 1100 changed
-------------------------------------------
5 0000 0000 0000 0000 0000 0101 correct
642 0000 0000 0000 0010 1000 0010 chanced
Does anybody have an idea, what could cause this error ?????
Thanks
Volker Berninger
> for saving numbers to a database I use an own datatype "Triple",
> which is a record of one word and one byte.
>
> type Triple = Record Lo:Word; Hi:Byte; end;
> ...
This doesn't speak specifically to your question, but in my opinion,
"Triple" is a really bad name for an integer data type seeing that
"Single" and "Double" are IEEE _real_ types.
Honestly, is storage really _that_ critical? Is shaving one byte off of
each longint in your database worth it considering the extra processing
necessary to convert?
Just my opinion.
AME
Yes, and that's not to mention the inherent inefficiency of generated
code to access even-word/odd-word data - data which isn't aligned for
optimal access. I don't know how his data is "packed" in memory, but I
suspect that the alignment varies and that access to individual variables
doesn't produce the most efficient code...
>Hi,
>
>for saving numbers to a database I use an own datatype "Triple",
>which is a record of one word and one byte.
>
>type Triple = Record Lo:Word; Hi:Byte; end;
>
>Function Triple_To_LongInt (T:Triple): LongInt;
>begin
> With T do Triple_To_Longint:= Lo + (LongInt(Hi) shl 16)
>end;
>
>procedure LongInt_To_Triple (L:LongInt; var T:Triple);
>begin
> With T do begin Lo:=L and $ffff; Hi:=L shr 16 end;
>end;
>
>I never had a problem to convert a triple to a longint and the function
>has been
>very often.
>Suddenly one of my users had the problem that few of the saved
>numbers changed during converting.
TP/BP 7.0 startup code sets a system variable Test8086
according to the type of processor the program is running
under.
Value Definition
0 Processor is an 8086
1 Processor is an 80286
2 Processor is an 80386 or later
The RTL tests the value in Test8086 and a number of routines
use 32-bit registers and 386 instructions in Test8086 is >=
2. The longint shift routines were one of the things that
were corrected in the 7.02 maintenance release.
Since the problem is recent, I assume you have the 7.01
fixes (time stamp of some TP/BP files == 7:01am). Because
the problem occurs only on "some" client machines, I suggest
that it may be possible that some interrupt service routines
or TSRs on those machines may not be properly saving 32-bit
registers.
You might try adding initialization code to your program to
limit the value of Test8086. Maybe something like:
If Test8086 > 1 Then Test8986 := 1;
You may also want to consider the following ways of
converting between longints and your triple.
FUNCTION Long(T:Triple): LongInt;
VAR i: RECORD
Case Integer of
1: (Trip: Triple);
2: (Long: Longint);
End;
Begin
i.Long := 0; { clear (set to zero) }
i.Trip := t;
Long := i.Long;
END;
PROCEDURE Trip(L:LongInt; var T:Triple);
TYPE Cast = RECORD
Case Integer of
1: (Trip: Triple); { your definition }
2: (Long: Longint);
END;
BEGIN
T := Cast(L).Trip;
END;
If you don't find it too cryptic or inconvenient, you can
make Cast a global declaration, then simply use
Cast(AnyLongint).Trip to convert a longint to Triple.
...red
--
Support the anti-Spam amendment
Join at http://www.cauce.org/
In a complimentary email, Babis Athineos, ba...@hol.gr
wrote:
>I looked hard to find the smile, but I didn't!
>
>Are you saying there is a tp/bp 7.02? (I thought 7.01 was the last one)
>
>Could you give more info?
>
>TIA
>
>Babis Athineos
>
>[cc by e-mail]
The article hasn't shown up on my news server yet, so I
decided to reply as if it had. :-)
You're right Babis, AFAIK 7.01 is the latest release. The
bad number was simply a typo. The spell checker helps
identify those occasions when I hit adjacent letters, but
what good is a spell checker when it comes to numbers? <LOL>
Sorry for any confusion.
...red
[cc sent to ba...@hol.gr]
>In article <3401bc95...@news.southeast.net>,
> rdo...@southeast.net (R.E.Donais) wrote:
>>The RTL tests the value in Test8086 and a number of routines
>>use 32-bit registers and 386 instructions in Test8086 is >=
>>2. The longint shift routines were one of the things that
>>were corrected in the 7.02 maintenance release.
>>
>>Since the problem is recent, I assume you have the 7.01
>>fixes (time stamp of some TP/BP files == 7:01am).
>
>I looked hard to find the smile, but I didn't!
>
>Are you saying there is a tp/bp 7.02? (I thought 7.01 was the last one)
>
>Could you give more info?
>
I replied under the original thread, but once again say it
as a simple typo.
AFAIK, 7.01 is the latest TP/BP version.
...red