
Hinweise, um die Bugs in TDI's GEMX.LENGTHEN & GEMX.SHORTEN zu beseitigen:

*****************************************************************************

(*$P-*)
PROCEDURE LENGTHEN (real: REAL);         (* 32 bit Real -> 64 bit LongReal.*)
 BEGIN  (* Offset of result: PMARK *)
   CODE ( 04E56H, 00000H, 048E7H, 0E000H, 0202EH, 00008H, 0E398H, 02400H,
          00280H, 000FFH, 0FFFFH, 00282H, 0FF00H, 00000H, 06612H, 07000H,
          07200H, 048EEH, 00003H, 00008H, 04CDFH, 00007H, 04E5EH, RTS,
          0E68AH, 0E288H, 0E292H, 00682H, 03800H, 00000H, 02200H, 0E688H,
          0E699H, 00281H, 0E000H, 00000H, 08082H, 060D6H) END LENGTHEN; 
                          (* ^ Bug entfernt: statt 07000H .    13.10.91 RS *)
                          (* Verlor das drittletzte Bit! *)

(* Bem.: Das im Zusammenhang mit LENGTHEN zu beobachtende arithmetische
         Aliasing ist eine Konsequenz der Verlngerungs-Methode!
         (Hat mit dem Bug nichts zu tun!)
*)

(*$P-*)
PROCEDURE SHORTEN (longreal: LONGREAL);  (* 64 bit LongReal -> 32 bit Real.*)
 BEGIN  (* Offset of result: PMARK +4 *)
   CODE ( 04E56H, 00000H, 048E7H, 0F000H, 04CEEH, 00003H, 00008H, 04840H,
          03400H, 00242H, 07FF0H, 06762H, 00442H, 03800H, 06B00H, 0005CH,
          00C42H, 00FFFH, 06E00H, 00058H, 0E94AH, 0760FH, 00700H, 06704H,
          008C2H, 00000H, 00240H, 0000FH, 008C0H, 00004H, 04840H, 00681H,
          01000H, 00000H, 06412H, 05280H, 07614H, 00700H, 0660AH, 0E288H,
          (*  ^  statt 00010H (Rundung in Bit 28 statt 20) *)
          0E291H, 00642H, 00100H, 06526H, 0E788H, 0E799H, 00201H, 00007H,
          08001H, 04840H, 00880H, 00007H, 0E25AH, 08042H, 04840H, 02D40H,
          0000CH, 04CDFH, 0000FH, 04E5EH, 04E75H, 07000H, 060F0H, 07004H);
   HALTX;                                            (* statt 07005H ^. RS *)
   CODE (UNLK, RTS); END SHORTEN;                                    (* RS *)


*****************************************************************************

Anhang (Disassemblings der originalen GEMX.LENGTHEN & GEMX.SHORTEN):

*****************************************************************************

  Auszug aus GEMX.DEC:
  PROCEDURE LENGTHEN(* ProcNum:28 *)(REAL);

*****************************************************************************

proc code, procnum = 28, entrypoint =     0H, number of bytes = 76
 DECODE --------                        INSTRUCTION
     0H        4E56 0000                LINK    A6,#0000H
     4H        48E7 E000                MOVEM.L #E000H,-(A7)
     8H        202E 0008                MOVE.L  0008(A6),D0
     CH        E398                     ROL.L   #1,D0
     EH        2400                     MOVE.L  D0,D2
    10H        0280 00FF FFFF           ANDI.L  #00FFFFFFH,D0
    16H        0282 FF00 0000           ANDI.L  #FF000000H,D2
    1CH        6612                     BNE     [12H] = 00000030H
    1EH        7000                     MOVEQ   #00H,D0
    20H        7200                     MOVEQ   #00H,D1
    22H        48EE 0003 0008           MOVEM.L #0003H,0008(A6)
    28H        4CDF 0007                MOVEM.L (A7)+,#0007H
    2CH        4E5E                     UNLK    A6
    2EH        4E75                     RTS
    30H        E68A                     LSR.L   #3,D2
    32H        E288                     LSR.L   #1,D0
    34H        E292                     ROXR.L  #1,D2
    36H        0682 3800 0000           ADDI.L  #38000000H,D2
    3CH        2200                     MOVE.L  D0,D1
    3EH        E688                     LSR.L   #3,D0
    40H        E699                     ROR.L   #3,D1
    42H        0281 E000 0000           ANDI.L  #E0000000H,D1
    48H        8082                     OR.L    D2,D0
    4AH        60D6                     BRA     [D6H] = 00000022H
  checksum: o.k.

*****************************************************************************

 Leider ergibt diese Proz. 'krumme' Verlngerungen
 (z.B. LONG (3.200000) = 3.200000048...).
 Der Grund ist das in REAL-Zahlen eingebaute arithmetische Aliasing:
 In der hheren Genauigkeit gibt es natrlich i.a. Zahlen, die wesentlich
 nher am wahren Wert (im Bsp.: 3.2) liegen als die der niedrigeren.

 Abhilfe: Entweder ein anderes LENGTHEN, oder folgender Vergrberungs-Trick:
  (Warum das funktioniert wei allein der groe Compi...)

PROCEDURE Long (r: REAL): LONGREAL; (* Fr fast 'exakte' Verl. mit Dez.-00.*)
 BEGIN RETURN (LONG (r * 1.0E6) / FLOATD (1000000)) END Long;

 Sonst bliebe wohl nur noch der (ziemlich lahme) Umweg ber die Dezimalen...

 brigens:
 Die Differenz der Offsets (Bias) der Exponenten (zw. REAL & LONGREAL)
 betrgt   1023 - 127 = 896 = 7 * 2^7 (daher kommt 38000000H = 0011100...).
 Formate:  REAL: v,e8,f23  => Zahlbereich 2^24 ~ 16000000 => max.  7 Stellen
       LONGREAL: v,e11,f52 => Zahlbereich 2^53 ~ 8* 10^15 => max. 16 Stellen


*****************************************************************************

  Auszug aus GEMX.DEC:
  PROCEDURE SHORTEN (* ProcNum:29 *) (LONGREAL);

*****************************************************************************

     0H       4E56 0000                LINK    A6,#0000H
     4H       48E7 F000                MOVEM.L #F000H,-(A7)
     8H       4CEE 0003 0008           MOVEM.L 0008(A6),#0003H
     EH       4840                     SWAP    D0
    10H       3400                     MOVE.W  D0,D2
    12H       0242 7FF0                ANDI.W  #7FF0H,D2
    16H       6762                     BEQ     [62H] = 0000007AH
    18H       0442 3800                SUBI.W  #3800H,D2
    1CH       6B00 005C                BMI     [005CH] = 0000007AH
    20H       0C42 0FFF                CMPI.W  #0FFFH,D2
    24H       6E00 0058                BGT     [0058H] = 0000007EH
    28H       E94A                     LSL.W   #4,D2
    2AH       760F                     MOVEQ   #0FH,D3
    2CH       0700                     BTST    D3,D0
    2EH       6704                     BEQ     [04H] = 00000034H
    30H       08C2 0000                BSET    #0000H,D2
    34H       0240 000F                ANDI.W  #000FH,D0
    38H       08C0 0004                BSET    #0004H,D0
    3CH       4840                     SWAP    D0
    3EH       0681 0010 0000           ADDI.L  #00100000H,D1
    44H       6412                     BCC     [12H] = 00000058H
    46H       5280                     ADDQ.L  #1,D0
    48H       7614                     MOVEQ   #14H,D3
    4AH       0700                     BTST    D3,D0
    4CH       660A                     BNE     [0AH] = 00000058H
    4EH       E288                     LSR.L   #1,D0
    50H       E291                     ROXR.L  #1,D1
    52H       0642 0100                ADDI.W  #0100H,D2
    56H       6526                     BCS     [26H] = 0000007EH
    58H       E788                     LSL.L   #3,D0
    5AH       E799                     ROL.L   #3,D1
    5CH       0201 0007                ANDI.B  #07H,D1
    60H       8001                     OR.B    D1,D0
    62H       4840                     SWAP    D0
    64H       0880 0007                BCLR    #0007H,D0
    68H       E25A                     ROR.W   #1,D2
    6AH       8042                     OR.W    D2,D0
    6CH       4840                     SWAP    D0
    6EH       2D40 000C                MOVE.L  D0,000C(A6)
    72H       4CDF 000F                MOVEM.L (A7)+,#000FH
    76H       4E5E                     UNLK    A6
    78H       4E75                     RTS
    7AH       7000                     MOVEQ   #00H,D0
    7CH       60F0                     BRA     [F0H] = 0000006EH
    7EH       7005                     MOVEQ   #05H,D0

    80H       4EB9 0000 0000           JSR     00000000H

*****************************************************************************

Bem.:  ADDI.L  #00100000H,D1 sorgt fr 'milde' Rundung in Bit 20 (statt 28).

