USE80.PAS 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. { FLOATING POINT PROCESSOR }
  2. Procedure USE_80(p1,p2,p3:a;var rez:a);
  3. type ref_real=^real;
  4. const real_size=sizeof(real);
  5. type real_string=array[1..real_size]of char;
  6. var i:integer; re1,re2,re3:real;
  7. c1,c2:char;X:MPD;
  8. the_a,the_D:longint;
  9. label 1;
  10. begin
  11. (********** ALL the operations should end with
  12. [ Forms REZ ] Goto 1
  13. or
  14. Forms RE1
  15. **********************************************)
  16. rez:=0; { in case of unsuccessful data returns NULL }
  17. if not PLSTR(P1,STR,L,FALSE,SV1) then goto 1;
  18. c1:=STR[1];if L=2 then c2:=STR[2] else c2:=' ';
  19. (*********************** first argument (p2) is not real ************)
  20. case c1 of (*1*)
  21. 'S':begin { String -> real }
  22. if not PLSTR(P2,STR,L,TRUE,SV1) then goto 1;
  23. system.VAL(SV1,re1,i);
  24. if i<>0 then goto 1;
  25. end;
  26. 'I':begin { Integer -> real }
  27. if not PLNUM(p2,IM[2]) then goto 1;
  28. re1:=IM[2]; { *1.0 }
  29. end;
  30. {$IFDEF xSUN}
  31. OTHERWISE
  32. {$ELSE}
  33. ELSE
  34. {$ENDIF}
  35. { Real -> ... }
  36. begin (*2*)
  37. if not PLSTR(P2,STR,L,FALSE,SV1) then goto 1;
  38. (* if L<>real_size then goto 1; *)
  39. re2:=ref_real(Addr(str[1]))^;
  40. (*********************** first argument (p2) is real (re2) ************)
  41. case c1 of (*3*)
  42. 'D':begin { Added in 2.21 29-JUN-92 }
  43. { Digit number before and after the dot in
  44. decimal numbers }
  45. rez:=NULL;
  46. if L=real_size then goto 1;
  47. lconc(rez,long_to_atom(ord(str[real_size+1])));
  48. lconc(rez,long_to_atom(ord(str[real_size+2])));
  49. goto 1;
  50. end;
  51. 'T': begin
  52. if (re2<-2147483648.999)or(re2>2147483647.999) then goto 1;
  53. if (re2<-2147483647.999) then IM[3]:=-maxlongint-1
  54. (* to prevent TRUNC error ! *)
  55. else IM[3]:=Trunc(re2);
  56. Gets1(rez,X.sa);
  57. with x.snd^ do begin dtype:=number;val:=IM[3];end;
  58. goto 1;
  59. end;
  60. 'Z': begin
  61. if not PLNUM(p3,IM[2]) then goto 1;
  62. (* A*100+D , D maybe negative *)
  63. the_A:=IM[2] div 100;
  64. the_D:=IM[2] mod 100;
  65. if the_D>50 then begin the_D:=the_D-100;Inc(the_A);end;
  66. SVAR:=REAL_TO_STRING_F(re2,the_A,the_D);
  67. i:=length(SVAR);
  68. PutAtm(SVAR[1],I,ATM);
  69. Gets1(rez,x.sa);
  70. with x.sad^ do begin Dtype:=atom;name:=atm;end;
  71. goto 1;
  72. end;
  73. 'R': begin (* (67.7689 2) -> 6776.89,-0.89 -> 6776.000 -> 67.760000 *)
  74. if not PLNUM(p3,IM[2]) then goto 1;
  75. for i:=1 to IM[2] do
  76. begin
  77. if abs(re2)>1E+37 then goto 1; (* To prevent float overflow *)
  78. re2:=re2*10.0;
  79. end;
  80. if Frac(re2)>0.5 then re2:=re2+1;
  81. if Frac(re2)<-0.5 then re2:=re2-1;
  82. re2:=re2-Frac(re2);
  83. for i:=1 to IM[2] do re2:=re2/10.0;
  84. re1:=re2;
  85. end;
  86. 'V': begin
  87. system.str(re2,SVAR);
  88. while SVAR[1]=' ' do delete(svar,1,1);
  89. i:=length(SVAR);
  90. PutAtm(SVAR[1],I,ATM);
  91. Gets1(rez,x.sa);
  92. with x.sad^ do begin Dtype:=atom;name:=atm;end;
  93. goto 1;
  94. end;
  95. 'Q':if re2>=0 then re1:=sqrt(re2) else goto 1;
  96. 'X':if abs(re2)<87 then re1:=exp(re2) else goto 1;
  97. 'L':if re2>0 then re1:=ln(re2) else goto 1;
  98. {$IFDEF xSUN}
  99. OTHERWISE
  100. {$ELSE}
  101. ELSE
  102. {$ENDIF}
  103. (*********************** second argument (p3) is also real (re3) ************)
  104. begin (*4*)
  105. if not PLSTR(P3,STR,L,false,SV1) then goto 1;
  106. re3:=ref_real(Addr(str[1]))^;
  107. case c1 of (*5*)
  108. '+': begin
  109. if (re2<>0)and(re3<>0) then
  110. if (ln(abs(re2))>87)or(ln(abs(re3))>87)then goto 1;
  111. re1:=re2+re3;
  112. end;
  113. '-': begin
  114. if (re2<>0)and(re3<>0) then
  115. if (ln(abs(re2))>87)or(ln(abs(re3))>87)then goto 1;
  116. re1:=re2-re3;
  117. end;
  118. '*':
  119. begin
  120. if (re2<>0)and(re3<>0) then
  121. if abs( (ln(abs(re2)))+ (ln(abs(re3))) )>87 then goto 1;
  122. re1:=re2*re3;
  123. end;
  124. '/':if re3<>0 then
  125. begin
  126. if (re2<>0)and(re3<>0) then
  127. if abs( (ln(abs(re2)))- (ln(abs(re3))) )>87 then goto 1;
  128. re1:=re2/re3;
  129. end
  130. else goto 1;
  131. '=':begin if re2=re3 then rez:=p2; goto 1; end;
  132. '>':begin if c2='=' then begin if re2>=re3 then rez:=p2 ; end
  133. else begin if re2> re3 then rez:=p2 ; end;
  134. goto 1;end;
  135. '<':begin
  136. if c2='=' then begin if re2<=re3 then rez:=p2 ; end
  137. else if c2='>' then begin if re2<>re3 then rez:=p2 ; end
  138. else if re2<re3 then rez:=p2 ;
  139. goto 1;end;
  140. {$IFDEF xSUN}
  141. OTHERWISE
  142. {$ELSE}
  143. ELSE
  144. {$ENDIF}
  145. goto 1; { Wrong real operation }
  146. end; (*5*)
  147. end; (*4*)
  148. end; (*3*)
  149. end; (*2*)
  150. end; (*1*)
  151. { This part processes only + - * / S(str->real) I(int->real) }
  152. ref_real(addr(SVAR[1]))^:=re1;
  153. ;
  154. PutAtm(SVAR[1],real_size,ATM);
  155. Gets1(rez,x.sa);
  156. with x.sad^ do begin dtype:=fatom; name:=atm;end;
  157. 1:
  158. end;