Newsgroup: it.comp.lang.delphi
Titolo: Conversione dati...

C'è nessuno che sa tradurre in delphi
la seguente formula scritta in Basic:
PRINT CVSMBF(X$);
Dovrebbe convertire il formato Microsoft in IEEE (4 byte)
Grazie Dany.

Ciao,

non ho VB sotto mano.
Se mi spieghi al volo questo formato ( con qualche esempio ) magari si fa
presto a scrivere una funzione o trovarne una già bella e pronta.
Riporta qualche esempio se puoi......ciaoooo !!!!
Antonio Tarolla

Ho trovato solo solo adesso questo documento sul formato MS:
1. Why use IEEE instead of MBF?
   IEEE was chosen as the math package for QuickBasic version 4.00 and
   Microsoft Basic Compiler 6.00 to allow for mixed-language calling
   capabilities. This ability is a very desirable feature. In addition
   to this feature, IEEE also is more accurate than Microsoft Binary
   Format (MBF). Calculations are performed in an 80-bit temporary area
   rather than a 64-bit area. (Note, the Alternate-Math Libraries use
   a 64-bit temporary area.) The additional bits provide for more
   accurate calculations and decrease the possibility that the final
   result has been degraded by excessive roundoff errors. Keep in mind
   that precision errors are inherent in any binary floating-point math.
   Not all numbers can be accurately represented in a binary
   floating-point notation.
   IEEE also can take advantage of a math coprocessor chip (such as
   the 8087, 80287, and 80387) for great speed. MBF cannot take
   advantage of a coprocessor.
2. If the calculations are more accurate, why are numbers such as
   .07#, 8.05#, and 9.96# displayed with a 1 in the 16th digit?
   Microsoft Binary Format (MBF) does not do this.
   MBF is accurate to 15 digits, while IEEE is accurate to 15 or 16
   digits. Since the numbers are stored in different formats, the
   last digit may vary. MBF double-precision values are stored in
   the following format:
      -------------------------------------------------
     |                            |    |                             |
     |8 Bit Exponent|Sign|   55 Bit Mantissa           |
     |                          | Bit|                             |
      -------------------------------------------------
   IEEE double precision values are stored in the following format:
      -------------------------------------------------
     |        |                | |                         |
     |Sign| 11 Bit Exponent|1|  52 Bit Mantissa        |
     | Bit  |                | |                         |
      -------------------------------------------------
                            ^
                            Implied Bit (always 1)
   You will notice that Microsoft Binary Format (MBF) has 4 more bits
   of precision in the mantissa. However, this does not mean that the
   value is any more accurate. Precision is the number of bits you are
   working with, while accuracy is how close you are to the real
   number. In most cases, the IEEE value will be more accurate because
   it was calculated in an 80-bit temporary. (When the IEEE standard
   was proposed, the main consideration for double precision values
   was range. As a minimum, the desire was that the product of any two
   32-bit numbers should not overflow the 64-bit format.)
3. Why doesn't my rounding algorithm eliminate the 1's in the 16th
   place?
   Your rounding algorithm is correctly rounding the numbers, but the
   extra digit is occurring because of the inherent rounding errors
   and format differences. For example, 6.99999999999999D-2 is rounded
   to .07 but the internal IEEE representation of the value is
   7.000000000000001D-2. (It is true that MBF displays the value as
   .07, but the difference in values is not considered as a problem. It
   is a difference between math packages.)
4. Why doesn't the STR$ function get the proper strings from either
   single or double-precision numbers?
   The STR$ function works correctly. The value placed in the string
   is the same as the value displayed on the screen with an
   unformatted PRINT. If the IEEE representation of .07 is
   7.000000000000001D-2, then the STR$ will return
   7.000000000000001D-2.
   There are a few ways to generate the desired string. The method
   used depends on the range of numbers, other resources available,
   and programmer's preference. Listed below are three possible
   routines that can be used. Keep in mind that as soon as the string
   is converted back to a number, it will no longer be truncated.
   Method 1
   --------
   If the range of numbers is between 2^32/100 and -2^32/100, the
   following method can be used:
   FUNCTION round2$ (number#)
   n& = number# * 100#
   hold$ = LTRIM$(RTRIM$(STR$(n&)))
   IF (MID$(hold$, 1, 1) = "-") THEN
      hold1$ = "-"
      hold$ = MID$(hold$, 2)
   ELSE
      hold1$ = ""
   END IF
   length = LEN(hold$)
   SELECT CASE length
   CASE 1
      hold1$ = hold1$ + ".0" + hold$
   CASE 2
      hold1$ = hold1$ + "." + hold$
   CASE ELSE
      hold1$ = hold1$ + LEFT$(hold$, LEN(hold$) - 2)
      hold1$ = hold1$ + "." + RIGHT$(hold$, 2)
   END SELECT
   round2$ = hold1$
   END FUNCTION
   The value being rounded is multiplied by 100# and the result is
   stored in a long integer. The long integer is converted to a string
   and the decimal point is inserted in the correct location.
==================================================
Io ho provato a fare una funzione peò mi da un'errore sugli ultimi byte!?
Non so perchè mi sfugge qualche cosa.
Dany

Ho risolto il problema con questa funzione
fatta proprio quest'oggi scervellandomi
fortemente........... :-))
// Per convertire il formato IEEEE -> MBF
Microsoft Binary format)
// ossia nel vecchio formato Microsoft Basic
Type
  myreal: Array[1..4] of byte;
function IEEEtoMBF(s: String): myreal;
Var
  AsSingle: Single;
  AsBytes: Array[0..3] of byte Absolute AsSingle;
  AsBStr: string;
  Position,i: Integer;
  msbin_exp,sign: Byte;
  msbin: myreal;
begin
  /* Ho utilizzato le string solo per mia necessità
  if length(s)=0 then s:='0';
  Position:=Pos('.',s);
  if Position > 0 then begin   /* il punto in virgola
     Delete(s,Position,1);
     Insert(',',s,Position);
  end;
  msbin_exp:=0;
  AsSingle := StrToFloat(s);
  // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  AsBStr := Format(' %.2u, %.2u, %.2u, %.2u',[AsBytes[0], AsBytes[1],
AsBytes[2], AsBytes[3]]);
  sign:=AsBytes[3] and 128;
  msbin_exp := msbin_exp+AsBytes[3] shl 1;
  msbin_exp := msbin_exp+AsBytes[2] shr 7;
  if (msbin_exp = 254) then msbin_exp:=1;
  msbin_exp:=msbin_exp+2;
  for i:=1 to 4 do begin msbin[i]:=0; end;
  msbin[4] := msbin_exp;
  msbin[3] := msbin[3]+sign;
  msbin[3] := msbin[3]+AsBytes[2] and 127;
  msbin[2] := Asbytes[1];
  msbin[1] := asBytes[0];
  IEEEtoMBF[1]:=msbin[1];
  IEEEtoMBF[2]:=msbin[2];
  IEEEtoMBF[3]:=msbin[3];
  IEEEtoMBF[4]:=msbin[4];
end;
Danile.

Prova con questa, la uso per leggere i dati Metastock.
function ConvMS(Var ms):Real48;
  var
    r:real48;
    ie : array [1..6] of Byte absolute r;
    m    : RealeMS absolute ms;
  begin
    FillChar(r, sizeof(r), 0);
    ie[1] := m[4];
    ie[4] := m[1];
    ie[5] := m[2];
    ie[6] := m[3];
    ConvMS := r;
  end;

ti ringrazio per questa funzione, ma l'avevo già.
Il mio problema era inverso, cioè da real a MS,
e lo risolto con la funzione che ho inviato.......
dany