The statement that gives the error is working fine when I evaluate it in the
evaluate/modify window.
Does anybody know how I can overcome that?
Thank you,
Rigas.
Rigas, Please
(1) Show us some code;
(2) The exact line causing error
(3) The exact error message; and
(4) The contents of the FPU Control Word using
Get8087CW before and after the error. (You
are trapping the exception aren't you?) Show it to
us in hex. Regards, JohnH
while (Delta > Delta_Tol) do
begin
Sat_Index := Min_Sat_Index;
for Sat := 1 to Num_Sat_Vis do
begin
Compute_Meas_SD(User_Params_Ptr, Sats_Useable[Sat_Index], SD1);
ERROR-->
Rn[Sat]:=SQRT(sqr(Xest[1]-X_Sat[Sat])+sqr(Xest[2]-Y_Sat[Sat])+sqr(Xest[3]-Z_
Sat[Sat]));
{ PGC 10.03.95 Following line to cure the Divide by zero error }
if Rn[Sat] = 0.0 then
Rn[Sat] := 0.1;
G[Sat,1] := (Xest[1] - X_Sat[Sat]) / Rn[Sat] / SD;
G[Sat,2] := (Xest[2] - Y_Sat[Sat]) / Rn[Sat] / SD;
G[Sat,3] := (Xest[3] - Z_Sat[Sat]) / Rn[Sat] / SD;
{They divide the geometry factor G by the Standard deviation for
the error. This could
create problems in the calculation of the Slopes, since the Inverse
matrices are also found
normalised to the SD}
G_R[Sat,1] := (Xest[1] - X_Sat[Sat]) / Rn[Sat];
G_R[Sat,2] := (Xest[2] - Y_Sat[Sat]) / Rn[Sat];
G_R[Sat,3] := (Xest[3] - Z_Sat[Sat]) / Rn[Sat];
case Sat_Type(Sats_Useable[Sat_Index]) of
Aid_Sat : begin
{ when Sats_Useable[Sat]
= 0 it is not really a satellite but the}
{ Baro measurement -
hence it has no effect on the clock offset. }
G[Sat,4] := 0.0;
G_R[Sat,4] := 0.0;
end; { Aid_Sat }
GPS_Sat, GLONASS_Sat, Geo_Sat : begin
G[Sat,4] := 1.0 / SD;
G_R[Sat,4] := 1.0;
end; { Nav Sat }
end; { case }
{ Y = Di - pseudo range }
Di[Sat] :=( G[Sat,1] * X_Sat[Sat]
+ G[Sat,2] * Y_Sat[Sat]
+ G[Sat,3] * Z_Sat[Sat] ) * SD;
Yest[Sat] := (Di[Sat] + R_Err_Pseudo[Sat]) / SD;
Yest_R[Sat] := Yest[Sat]*SD;
inc(Sat_Index);
end;
Matrix_Mult2(@G, @Yest, GT_Y);
Matrix_Mult1(@G, @G, GT_G);
Calc_Inv_Mat(GT_G, GT_G_inv, No_Inverse); { Falls Over Here }
Matrix_Mult2(@G_R, @Yest_R, GT_Y_R);
Matrix_Mult1(@G_R, @G_R, GT_G_R);
Calc_Inv_Mat(GT_G_R, GT_G_inv_R, No_Inverse_R);
if not(No_Inverse) then
begin
Matrix_Mult3(@GT_G_inv, @GT_Y, New_Xest);
{ Matrix_Mult4(G, New_Xest, New_Yest); } { this line is not
needed }
Delta := SQRT( sqr(Xest[1]-New_Xest[1])
+ sqr(Xest[2]-New_Xest[2])
+ sqr(Xest[3]-New_Xest[3])
+ sqr(Xest[4]-New_Xest[4]) );
Xest[1] := New_Xest[1];
Xest[2] := New_Xest[2];
Xest[3] := New_Xest[3];
Xest[4] := New_Xest[4];
end; { if}
Iter_Count := Iter_Count + 1;
Failed_to_Converge := Iter_Count >= Max_Iterations;
if (Failed_to_Converge) or (No_Inverse) then
begin
Xest[1] := XYZT_on_fail;
Xest[2] := XYZT_on_fail;
Xest[3] := XYZT_on_fail;
Xest[4] := XYZT_on_fail;
Delta := 0; { to escape while loop }
if dosubset<>2 then {When the Nortel executes normally}
begin
Initialise_Rx_Output(Rx_Output_Ptr^,
UnAvailable,
UnAvailable,
UnAvailable,
Failed_Iteration);
end;
end {if}
end; {while}
Thank you,
Rigas
Project Rigas.Exe raised exception class EInvalidOp with message 'Invalid
floating point operation'. Process stopped use run to continue.
I had the same error before when I was calling a function. I then changed
that function to a procedure and I started getting that error at the next
statement.
Rigas
> John, The error is on the 8th line of the code I give you here.
> The Get8087CW gives 4978.
That 4978 decimal is $1372 hex. That is the normal value.
Is the error in the Compute_Meas_SD or the next line?
I could not tell because of the wrapping.
> I am not trapping the exception (I am just trying to find
> out how I can do it and what are its advantages).
It's easy just wrap the code in a try-except-end block:
Try{Except}
MyLoc :=1;
Compute_Meas_SD
(User_Params_Ptr, Sats_Useable[Sat_Index], SD1);
MyLoc :=2;
Rn[Sat]:=SQRT( sqr(Xest[1]-X_Sat[Sat]) +
(Xest[2]-Y_Sat[Sat]) + sqr(Xest[3]-Z_Sat[Sat]));
Except
On e: Exception do begin
{ the "e" is a limited scope var created and set to the exception}
cw := GetFPUCW; {cw should be a word var}
ShowMessage('e.Message +
Format(' MyLoc=%d, FPUCW=$%4x[MyLoc,cw])');
raise; {re-raises the same exception}
end;
End{Except};
Regards, JohnH
Rigas, Just guessing, it sounds like the procedure
Compute_Meas_SD (or something that it is calling)
is masking out interrupts via the control word,
making an error and reenabling the interrupts
without clearing the pending interrupt. Graphics
code used to be bad about this. Regards, JohnH
The same statements have already been executed once. The program re-executes
them for a subset of the previous set of values used.
It drives me mad, I do not understand why it happens. I changed a part of
the code that was giving me the same error, solving the problem but getting
the same error next line... It seems that it could be a system error not a
code error but I better do not say more since it could be all wrong.
Best Regards,
Rigas.
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f0f4062$1...@newsgroups.borland.com...
It is very annoying spending so much time on this program and then to find
out that you get a perculiar problem.
Best Regards
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f0f...@newsgroups.borland.com...
Rigas,
Can you write out the offending values as a packed binary
record to a file, the next time they are trapped, before they are
lost?
Rgds, JohnH
> The error appears in the next line Rn[sat]:=sqrt....
Rigas,
Do you know what the result of trying to take the
square root of a negative number is? Yes, you guessed
correctly "Invalid floating point operation." Though I
cannot see how that could be possible if your code is
transcribed correctly.
> I broke up that calculation into a number of terms and
> I was getting the same error at the new line ...
I think that you should check all the inputs with IsNAN()
and IsInfinity() like this:
Assert(not IsNAN(Xest[1]) and not IsInfinity(Xest[1]));
Assert(not IsNAN(X_Sat[Sat]) and not IsInfinity(X_Sat[Sat]));
and etc. for the others.
Rn[Sat] :=SQRT( sqr(Xest[1]-X_Sat[Sat]) +
sqr(Xest[2]-Y_Sat[Sat]) + sqr(Xest[3]-Z_Sat[Sat]) );
I am still suspicious of Compute_Meas_SD(). Does it do
anything with Set8087CW() or SetExceptionMask()?
Have the sqr() or sqrt() functions been replaced?
Regards, JohnH
Rigas.
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f0f5c21$1...@newsgroups.borland.com...
function SetX87CW (NewCW: Word): word;
{ returns old and sets new FPU control word. }
asm {Part of this copied from D5 System.pas.}
FNCLEX // Don't raise pending exceptions enabled by the new flags.
MOV Default8087CW,AX // Copy new value to location in System unit.
FStCW [Result] // Copy old value for returning to caller.
FLDCW Default8087CW // Change the X87 control word here.
end;
You can use it like this:
Var Sav87CW: word;
...
Sav87CW := SetX87CW (<NewCW>);
... your special work ...
SetX87CW (Sav87CW);
It works at the point that I used it but I get the same error at another
point (in another unit actually).
Does that help?
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f0f5c21$1...@newsgroups.borland.com...
Old version:
function Compute_Meas_SD(
const User_Params_Ptr : UserParameters_Pointer_Type;
const Sat : Sat_Index_Type ) : real ;
var forgetaboutmore:Integer;
begin
forgetaboutmore:=0;
{ PGC 6.3.95 aiding Meas SD is assumed to be 10.0 - Now changed }
with User_Params_Ptr^.DGNSS_Record do
begin
* if (User_Params_Ptr^.DGNSS_Record.DGNSS_Status = Disabled) then
begin { NOT DIFFERENTIAL }
forgetaboutmore:=1;
case Sat_Type(Sat) of
** GPS_Sat : Compute_Meas_SD := GPS_URA;
GLONASS_Sat : Compute_Meas_SD := GLO_URA;
Geo_Sat : Compute_Meas_SD := Geo_URA;
Aid_Sat : Compute_Meas_SD := AID_URA;
end; { case }
end;
end;
with User_Params_Ptr^.DGNSS_Record do
begin
*** if (User_Params_Ptr^.DGNSS_Record.DGNSS_Status = Enabled) AND
(forgetaboutmore=0) then
begin
case Sat_Type(Sat) of
GPS_Sat : Compute_Meas_SD := GPS_Sigma;
GLONASS_Sat : Compute_Meas_SD := GLO_Sigma;
Geo_Sat : Compute_Meas_SD := Geo_Sigma;
**** {Aid_Sat : Compute_Meas_SD := Aid_Sigma;}
end; { case }
end; { else }
end; { with }
end; { Compute_Meas_SD}
Now, the problem was coming up starting on the line with the three
asterisks. Although the condition was not satisfied (the program has found
correctly that the condition at the line with the one * was satisfied
executing the line with the 2 *) the program was giving me an error at the
line with the 4 *.
So it was executing a command that it should not and it was giving an error
at a line that has nothing wrong. Crazy enough? No? Ok. I changed it to the
procedure:
procedure Compute_Meas_SD(User_Params_Ptr : UserParameters_Pointer_Type;
Sat : Sat_Index_Type;
var SD:Real );
var forgetaboutmore:Integer;
begin
forgetaboutmore:=0;
{ PGC 6.3.95 aiding Meas SD is assumed to be 10.0 - Now changed }
with User_Params_Ptr^.DGNSS_Record do
begin
if (User_Params_Ptr^.DGNSS_Record.DGNSS_Status = Disabled) then
begin { NOT DIFFERENTIAL }
forgetaboutmore:=1;
if (Sat>0) AND (Sat<=Max_GPS_Satellites) then
begin
SD := GPS_URA;
end;
if (Sat>Max_GPS_Satellites) AND (Sat<=(Max_GPS_Satellites +
Max_GLONASS_Satellites)) then
begin
SD := GLO_URA;
end;
if (Sat>(Max_GPS_Satellites + Max_GLONASS_Satellites)) then
begin
SD := GEO_URA;
end;
if (Sat>Max_GPS_Satellites) AND (Sat<=(Max_GPS_Satellites +
Max_GLONASS_Satellites)) then
begin
SD := AID_URA;
end;
end
else
begin
if (Sat>0) AND (Sat<=Max_GPS_Satellites) then
begin
SD := GPS_Sigma;
end;
if (Sat>Max_GPS_Satellites) AND (Sat<=(Max_GPS_Satellites +
Max_GLONASS_Satellites)) then
begin
SD := GLO_Sigma;
end;
if (Sat>(Max_GPS_Satellites + Max_GLONASS_Satellites)) then
begin
SD := GEO_Sigma;
end;
if (Sat>Max_GPS_Satellites) AND (Sat<=(Max_GPS_Satellites +
Max_GLONASS_Satellites)) then
begin
SD := AID_Sigma;
end;
end;
end;
end; { Compute_Meas_SD}
Problem was solved but after execution exits the procedure going back to the
calling procedure, it is giving me an error to the first simplest arithmetic
operation.
I am too young to get mad now... :-)
Best Regards,
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f0f...@newsgroups.borland.com...
"Rigas Ioannides" <r.ioa...@ntlworld.com> wrote in message
news:3f0f6494$1...@newsgroups.borland.com...
I changed this initialisation before the main task is performed to zeros and
the program works fine.
Hereby is all that I have done:
Xest[1] := 0;{Computed_position.X;}
Xest[2] := 0;{Computed_position.Y;}
Xest[3] := 0;{Computed_position.Z;}
Xest[4] := 0;{Computed_position.Clock_Offset;}
The computed_position is defined as
var Computed_Position : Position_Type;
where position type is:
Position_Type = Record
X : Real;
Y : Real;
Z : Real;
Lat : Real;
Lon : Real;
Height : Real;
Clock_Offset : Real;
end; { record }
It would be great to let me know what you think that was going wrong.
Notice that in BP7 this thing works fine. I just have to see if the two
programs give identical results.
Thank you very much for your time,
My Best Regards,
Rigas.
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f0f2fbd$1...@newsgroups.borland.com...
Interesting! I wrote that, years ago. My current version has a
FWAIT line before the FLDCW line.
Since you understand that, you may want to use the following
GetX87SW to fetch the pending interrupt status bits. The
one you are looking for is
$0001 -- IM (Invalid op interrupt Mask)
Function GetX87SW: word; // Assembler;
ASM
FStSW [Result]
End;
(* CW Mask bits prevent interrupt when true:
(Pending interrupt flags in status word have matching positions.) )
$0001 -- IM (Invalid op interrupt Mask)
$0002 -- DM (Denormalized op interrupt Mask)
$0004 -- ZM (Zero divide interrupt Mask)
$0008 -- OM (Overflow interrupt Mask)
$0010 -- UM (Underflow interrupt Mask)
$0020 -- PM (Loss of precision interrupt Mask) }
{ CW Control bits change operation:
$0300 -- PC (Precision Control mask)
$0C00 -- RC (Rounding Control mask)
$1000 -- IC (Infinity Control mask) *)
Regards, JohnH
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f0f6c94$1...@newsgroups.borland.com...
Good. However, I still think that you need
(1) to have some code ready to check the status of the FPU
with GetX87SW() and the IsNAN() and IsInfinite(). You
need to know how the error propagates.
(2) to replace "real" with "double" else you will have trouble
in future.
(3) you need to clean up the code in Compute_Meas_SD
Either use the "with User_Params_Ptr^.DGNSS_Record" clause
or don't use it, but don't mix it.
(Very readable code is very fixable code.)
I used to work with "NORAD elements". Ever hear of those?
Rgds, JohnH
The two compiled programs (with BP7 and Delphi7) do not give identical
results so I have to see if there is a misusage of a function by Delphi with
respect to its usage in BP7.
I will come back to you when I finish,
Thank you very much for your help
Rigas.
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f0f73b2$1...@newsgroups.borland.com...
Check the meaning of type "real" in BP7.
I suspect that is called "Real48" in D7.
Regards, JohnH
Shall I change the Real to Double or to Real48?
Best Regards,
Rigas
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f10...@newsgroups.borland.com...
Rigas, I cannot vouch for that statement that "different compilers
behave differently". Some people were remarking recently that
the generators were the same, since TP days.
> I think that the random number is in the CRT unit. Do you know
> how I can make random in Delphi 7 to give the same results as
> the random in BP 7?
Sure; just use the same genrator as BP7 uses. If you cannot find
out what it is, then I would use the one from DP7 in your BP7
code.
> Shall I change the Real to Double or to Real48?
On the PC, double is much faster and more standard across different
languages. SizeOf double vars is 8 bytes.
Real48 is the same as the old TP (Turbo Pascal) "real". Size of
Real48 vars is 6 bytes.
The IsNaN and IsInfinity functions only work on single, double, and
extended.
Rgds, JohnH
Yes I did not say it as it was. I just copy what Delphi says:
'Because the implementation of the Random function may change between
compiler versions, we do not recommend using Random for encryption or other
purposes that require reproducible sequences of pseudo-random numbers.'
> Sure; just use the same genrator as BP7 uses. If you cannot find
> out what it is, then I would use the one from DP7 in your BP7
> code.
I cannot I may need a bit of more help here. I try to find a function called
Random in the built in units and libraries but I cannot find smth.
Anyway I am debugging both compiled versions and the Random function in BP
returns a totally different number than the same statement in DP7.
I will definitely be with Delphi's side on that one at least, but I need to
see if the results I am taking from the DP7 compiled version are identical
to those of BP7 to make sure that everything works as it should be.
>
> > Shall I change the Real to Double or to Real48?
>
> On the PC, double is much faster and more standard across different
> languages. SizeOf double vars is 8 bytes.
>
> Real48 is the same as the old TP (Turbo Pascal) "real". Size of
> Real48 vars is 6 bytes.
>
> The IsNaN and IsInfinity functions only work on single, double, and
> extended.
>
> Rgds, JohnH
>Thank you
Rigas.
>I think that the problem may also arise from the Random function. Delphi
>says that different compilers behave differently to that function with the
>same random seed number.
>I think that the random number is in the CRT unit. Do you know how I can
>make random in Delphi 7 to give the same results as the random in BP 7?
>Rigas
>"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
>news:3f10...@newsgroups.borland.com...
>> Check the meaning of type "real" in BP7.
>> I suspect that is called "Real48" in D7.
Borland newsgroup guidelines require that quoting should include only
what needs to be quoted; they are a subset of the Usenet guidelines,
which also call for responses to follow that they quote.
I don't think Delphi says that compilers do behave differently; only
that they may do so. The following program gives identical output in
BP7 & D3 :
var J, K : integer ;
begin
RandSeed := 0 ;
for J := 0 to 5 do begin
Writeln(J:4, RandSeed:12) ;
K := Random(6) ;
end ;
end.
Randomize may also differ; and in fact does between BP7 & D3.
Random, and no doubt Randomize, is not in the Crt unit; the program
needs no uses clause.
<URL:http://www.merlyn.demon.co.uk/pas-rand.htm> gives information
sufficient to implement the generator in pure Pascal, making it then
independent of subsequent changes in the Borland one.
--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
For news:borland.*, use their server newsgroups.borland.com ; but first read
Guidelines <URL:http://www.borland.com/newsgroups/guide.html> ff. with care.
Still I am fairly sure that BP7 and DP7 have different implementations for
the random functions, since my two compiled versions reach the statement of
the random function having exactly the same values in their (same)
variables.
Unless smth else goes completely wrong but if it does at least it should be
present itself in other parts of the program as well.
I have not used Randomize in my program since I ask the user for the random
number seed.
Actually in my previous message I have corrected what I have said about the
Delphi's help file.
I have Delphi 2 which I have not tried yet, but I think that this compiler
version may have the same implementation of random function as BP7 or at
least the chances are better since you saythat it gives same results with
DP3.
Regards,
Rigas
Regardless of TP or Delphi version you can locate "system.pas" and search
for the word "Randseed" inside that module. Somewhere you will find the
following two lines
IMUL EDX,RandSeed,08088405H
INC EDX
as they are in Delphi 5, or similar lines as they might be implemented in
other versions.
Here "08088405H" is the multiplier and +1 (INC) is the addend used in
the Lehmer algorithm which is the base for (almost) any pseudo random
number generator. EDX is a 32 bits register defining the word length.
Identical multiplier, addend and word length in two different implentations
mean that the two generators are identical.
Sven
"Sven Pran" <no.d...@mail.please> wrote in message
news:3f11...@newsgroups.borland.com...
If you do not find it I guess you have a version of TP and/or Delphi which
do not include that source.
regards Sven
"Rigas Ioannides" <r.ioa...@ntlworld.com> wrote in message
news:3f116d56$1...@newsgroups.borland.com...
If I replace the system.dcu of Delphi 7 with the system.dcu of BP7 I will
probably see if there is smth different.
I have used the small program:
RandSeed := 0 ;
for J := 0 to 5 do begin
K := Random;
Writeln(J:4, RandSeed:12,K:7:3) ;
end ;
in both BP7 and Delphi7. K is giving completely different values for the
same seed number.
Best Regards,
Rigas
But you can easily investigate your random generator in another way:
var
A, C : integer;
.......
Randseed := 0;
Random;
C := Randseed;
RandSeed := 1;
Random;
A := RandSeed - 1;
You now have the multiplier (A) and the addend (C) and can evaluate
whether your generators are equivalent or not.
This little test does not reveal the cycle length, but I assume with rather
great confidence that this is 2^32 anyway. An easy but not failsafe way
of verifying this is to include the statement: Z := sizeof(Randseed);
Z (which is also integer) should receive the value 4.
Regards Sven
"Rigas Ioannides" <r.ioa...@ntlworld.com> wrote in message
news:3f1189a0$1...@newsgroups.borland.com...
Using something like the code I posted yesterday, it should be possible
to determine whether the later Delphi generators match the form of the
older ones, and if so what the constants are. Perhaps someone with D>3
could try it?
<URL:http://www.merlyn.demon.co.uk/pas-rand.htm> :
I have read that :- Random implementation in Delphi (and Borland Pascal)
is as follows: Pseudorandom longint sequence is implemented as a
congruential generator with the formula X[n+1] = 134775813*X[n] + 1 (mod
2^32) ; my tests support this, for BP7 & D3. It can be shown that the
sequence has full period (its length is 2^32).
So set RandSeed to 0, and for BP7 & D3 the first few values of RandSeed
will be
0 0
1 1
2 134775814
3 -596792289
4 870078620
5 1172187917
--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.
With Delphi 7:
C=1,A=134775814,Z=4.
But I have also used the previous code:
RandSeed := 0 ;
for J := 0 to 5 do begin
K := Random;
Writeln(J:4, RandSeed:12,K:7:3) ;
end ;
and K derived had totally different values. Anyhow, is it possible to get
the source code for the Random function in BP7 so that I can name it as
Random_1 and use it instead of Random in Delphi?
Regards,
Rigas
RandSeed := 0 ;
for J := 0 to 5 do begin
K := Random;
Writeln(J:4, RandSeed:12,K:7:3) ;
end ;
in both BP7 and Delphi7. RandSeed was exactly the same between the two
programs (BP7 and DP7). The difference was in K. K is giving completely
different values for the
same seed number.
For DP7:
J RandSeed K
0 1 0
1 134775814 0.031
2 -596792289 0.861
3 870078620 0.203
4 1172187917 0.273
5 -1410233534 0.672
For BP7:
J RandSeed K
0 1 0.5
1 134775814 0.531
2 -596792289 0.361
3 870078620 0.703
4 1172187917 0.773
5 -1410233534 0.172
The difference in absolute value seems to be 0.5.
The exact codes were:
DP7:
RandSeed := 0 ;
for J := 0 to 5 do begin
K := Random;
Writeln(J:4, RandSeed:12,K:7:3) ;
end ;
BP 7:
RandSeed := 0 ;
for J := 0 to 5 do begin
K := Random;
Writeln(J:4, RandSeed:12,K:7:3) ;
end ;
Thank you,
Rigas
Rigas, Did you mention the type of K somewhere?
Is it a double? How does the 32-bit random integer
get converted to K? Regards, JohnH
Sven, I do not know what you mean about identical since K results in
different values. RandSeed values are identical, but K values differ by 0.5.
Has anybody tried the K values, in case I have done smth wrong?
Regards,
Rigas.
"John Herbster (TeamB)" <herb-sci1_at_sbcglobal.net> wrote in message
news:3f11ce2e$1...@newsgroups.borland.com...
And that is the important symptom! For some reason unknown to me BP7
apparently
treats Randseed as a signed 31bit integer while Delphi treats Randseed as an
unsigned
32bit intgeger (internally). This means that for BP7 a randseed value of
zero is in the
center of the interval (0.5) while for Delphi it is at the lower limit
(0.0).
This may have something to do with the internal representation of floating
point numbers
in BP7, I do not understand how or why, and without access to system.pas it
is rather
hopeless to try making a guess.
My recommendation is that you should stick to the Delphi implementation and
if you
need a compatible random generator in BP7 you should copy the Delphi
generator into
your private library and use it from there for BP7.
regards Sven
This sounds ridiculous, but as you have found according to a separate post
your two random generators are identical.
regards Sven
I don't have it - a cheapskate Delphi 3 installation, bought from
Borland.
>Here "08088405H" is the multiplier and +1 (INC) is the addend used in
>the Lehmer algorithm which is the base for (almost) any pseudo random
>number generator. EDX is a 32 bits register defining the word length.
That is the value used in my D3 & BP7.
>Identical multiplier, addend and word length in two different implentations
>mean that the two generators are identical.
(To a later SP post) : To use a 32-bit algorithm of that form but with
constants not giving a 2^32 cycle length would be highly incompetent or
exceedingly subtle. But the length can be checked easily enough by
running for a full cycle - the wait for the result is not too great, and
one can go and make a cup of tea meanwhile. That would not apply,
though, for 48- or 64- bit algorithms such as
X[n+1] = 6364136223846793005*X[n] + 1 (mod 2^64)
Can someone post the constants for D6 & D7 ?
Has anyone investigated the situation for Javascript Math.Random()?
There, no seed is exposed, and the only accessible result is a Double,
0.0 <= D < 1.0 (but Opera can give D = 1.0).
--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Delphi 3 Turnpike 4 ©
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.bancoems.com/CompLangPascalDelphiMisc-MiniFAQ.htm> clpdmFAQ;
<URL:http://www.borland.com/newsgroups/guide.html> news:borland.* Guidelines
"Sven Pran" <no.d...@mail.please> wrote in message
news:3f11dcbc$1...@newsgroups.borland.com...
Internally the random generator works only on RandSeed, making a new
value in Randseed for each call to "Random". Presenting K (in your case) is
part of what I would call the routines "external" to the generator.
It would be interesting to know what result you get from the following
statements:
var
N : integer;
.....
Randseed := 0;
N := Random(100);
In Delphi you should get 0 (zero) but do you get 0 or 50 in BP7?
regards Sven
> >Here "08088405H" is the multiplier and +1 (INC)
> That is the value used in my D3 & BP7.
> > Identical multiplier, addend and word length in two different
> > implentationsmean that the two generators are identical.
> ...
> Can someone post the constants for D6 & D7 ?
D5 and D7 have same "08088405H" is the multiplier
and +1 increment -- and period is a full 2^32.
Rgds, JohnH
writeln(Random:4:3)
which I have included in both.
BP7 gives 0.531 and Delphi gives 0.31.
Regards,
Rigas
I have a hunch that you could try setting the following compiler options
for your BP7 compiler: {$N+,E-} meaning that your program will run
on a CPU with math features present (N+) and that the compiler shall
not include software emulators for floating-point variables (E-).
However, when looking through my old BP7 manual I find that BP7
apparently does not support 32 bits registers at all; which really means
that even the processing of 32 bits "longinteger"s must be carried out
internally by emulators. I think you have reached some limitation on
what you can achieve with BP7.
Here are the implementations of integer-Random and extended-random
from Delphi 5, but I hardly believe that you can have any use of them.
One little detail that worries me is the IMUL statements, they do not
conform to the syntax description I have in my instruction set reference.
(What IMUL does is to multiply RandSeed with 08088405H
and place the lower 32 bits of the result truncated into EDX).
procedure _RandInt;
asm
{ ->EAX Range }
{ <-EAX Result }
IMUL EDX,RandSeed,08088405H
INC EDX
MOV RandSeed,EDX
MUL EDX
MOV EAX,EDX
end;
procedure _RandExt;
const two2neg32: double = ((1.0/$10000) / $10000); // 2^-32
asm
{ FUNCTION _RandExt: Extended; }
IMUL EDX,RandSeed,08088405H
INC EDX
MOV RandSeed,EDX
FLD two2neg32
PUSH 0
PUSH EDX
FILD qword ptr [ESP]
ADD ESP,8
FMULP ST(1), ST(0)
end;
regards Sven
"RTI" <Ri...@caaisn.leeds.ac.uk> wrote in message
news:3F1299EE...@caaisn.leeds.ac.uk...
Mmm. So it is a design 'fault'.
>
> I have a hunch that you could try setting the following compiler options
> for your BP7 compiler: {$N+,E-} meaning that your program will run
> on a CPU with math features present (N+) and that the compiler shall
> not include software emulators for floating-point variables (E-).
>
> However, when looking through my old BP7 manual I find that BP7
> apparently does not support 32 bits registers at all; which really means
> that even the processing of 32 bits "longinteger"s must be carried out
> internally by emulators. I think you have reached some limitation on
> what you can achieve with BP7.
Yes, I will give it a shot though since I want to make sure that all the
rest procedures and function of my BP7 program work as they should.
Sven do you suspect of a reason for getting a Invalid floating point
operation with the runtime error message:
Project Rigas.Exe raised exception class EInvalidOp with message Invalid
floating point operation. Process stopped use run to continue.
We have found out that by changing the initialisation values of some
variables, the problem was solved.
Best Regards,
Rigas
.........
> Sven do you suspect of a reason for getting a Invalid floating point
> operation with the runtime error message:
>
>
> Project Rigas.Exe raised exception class EInvalidOp with message Invalid
> floating point operation. Process stopped use run to continue.
>
> We have found out that by changing the initialisation values of some
> variables, the problem was solved.
That can happen for a wide variety of reasons, but they will all probably
have one "feature" in common: Invalid source operand format or value;
including attempting to operate on a bit string defined as "NotANumber"
or illogic arithemtic performed on bitstrings defined as infinites. An
attempt
to calculate the square root of a negative number (except negative zero)
will produce this interrupt.
From your description my best guess is that you have had randomly initiated
floating-point variables and tried to perform some arithmetic on them before
they were properly initialized.
regards Sven
It is an initialisation matter, so I think it is ok now.
Best Regards,
Rigas
> I think that you should check all the inputs with IsNAN()
> and IsInfinity() like this:
> Assert(not IsNAN(Xest[1]) and not IsInfinity(Xest[1]));
> Assert(not IsNAN(X_Sat[Sat]) and not IsInfinity(X_Sat[Sat]));
> and etc. for the others.
> Rn[Sat] :=SQRT( sqr(Xest[1]-X_Sat[Sat]) +
> sqr(Xest[2]-Y_Sat[Sat]) + sqr(Xest[3]-Z_Sat[Sat]) );
>
> I am still suspicious of Compute_Meas_SD(). Does it do
> anything with Set8087CW() or SetExceptionMask()?
> Have the sqr() or sqrt() functions been replaced?
>
> Regards, JohnH
>
>
This suggests to me that your BP7 code is using the 6-byte
software type real and *not* using the type double. Unless
you are just trying to validate old data, please use the type
double for your floating point numbers.
> It is an initialization matter, so I think it is ok now.
An initialization matter? Do you mean that you were trying
to compute with un-initialized values? That is a no-no; and,
of course, it can be just as wrong to use 0 when the true
value is unknown.
For my data, I deliberately use a NaN, when the true
value is unavailable; then, if in the calculations, an attempt
to use it is made, it generates an exception to let my
program immediately handle it, or gets silently carried
through to the end results to let the user of the data know
that there was a problem.
Regards, JohnH
If you bought the extra RTL code with BP7, you have the source in
...\rtl\sys\rand.asm. I don't know how much effort would be needed to
directly convert this (copyrighted) 16-bit ASM code for use with Delphi.
The underlying method is given in my <URL:http://www.merlyn.demon.co.uk/
pas-rand.htm>; I recommend that you read it, and <URL:http://www.merlyn.
demon.co.uk/programs/delprand.pas>.
Today's delprand.pas has, in addition, code to emulate Random and
Random(N) in BP7 & D3.
Question :
{$IFDEF PASCAL}
{$Q-} RS := RS*$08088405 + 1 {$Q+} ;
Write(RS:14) ;
{$IFDEF DELPHI}
{$Q-} RS := RS*$08088405 + 1 ; {$Q+}
RS := RS - Trunc(RS/4294967296.0)*4294967296.0 ;
Write(RS:14:0) ;
In Pascal, RS is longint, and the obvious code works. In Delphi, it did
not; I've used the above, with RS of type comp. Is there anything
better; anything that will work for both cases?
--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
They are not completely different; as fixed-point binary fractions, they
differ by a single bit. I suspect that the cause may be related to the
different-length types in the languages.
What you find agrees with what is given in my <URL:http://www.merlyn.dem
on.co.uk/pas-rand.htm>; I recommend that you read it.
If Random(N), rather than Random, is called, I find that BP7 and D3 give
the same result from the same RandSeed.
Done. :-)
> An initialization matter?
Yes.
>Do you mean that you were trying
> to compute with un-initialized values?
Yes.
>That is a no-no;
Yes. :-)
and,
> of course, it can be just as wrong to use 0 when the true
> value is unknown.
I am calculating those parameters (Xest) later in the program. Thus I have
just initialised
them to their previous values. Some times though there is no need to
calculate Xest[4] variable, and somehow (after the second loop) this gets
to be NaN.
I think it is ok if I initialise them to 0 (it does not really matter to the
calculation of the rest variables) but you are right, I definetely have to
use smth more sophisticated.
> For my data, I deliberately use a NaN, when the true
> value is unavailable; then, if in the calculations, an attempt
> to use it is made, it generates an exception to let my
> program immediately handle it, or gets silently carried
> through to the end results to let the user of the data know
> that there was a problem.
It is a huge and complicated program but it worths trying ti improve it.
> Regards, JohnH
>
Thank you very much John,
My Best Regards,
Rigas.
Thank you Sven,
Rigas
Thanks. I can now reproduce the sequence in BP7, D3, and from what you
say D5 & D7; and so probably for anything in between.
I can also reproduce BP7 Randomize; and I think that of D3, though it
needs testing elsewhere. Results are compatible with
RandSeed := Milliseconds since midnight UTC, to OS resolution ;
I'm putting the new delprand.pas and its D3 EXE - console mode - and a
ZIP of both in <URL:http://www.merlyn.demon.co.uk/programs/> in case
anyone would care to try; the program should be innocuous. It outputs
three tables, and for me the last column of the last table is all
3600000, which is (local time - GMT) in milliseconds. Americans should
currently get that multiplied by a small negative integer; Indians by
perhaps +4.5.
Investigation of Randomize result changes
Time msec Diffmsec; RandSeed msec-RandSeed
0.750253588 64821910 60 61221910 3600000
0.750254167 64821960 50 61221960 3600000
...
That's D3 in Win98; results may depend on OS.
--
© John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME. ©
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;