zum leidigen Thema double

OP #458636
Lesenswert?

Gleich vorweg, ich möchte keine erneute Diskussion zum Thema double 
anzetteln. Trotzdem habe ich das Problem, dass ich mit einem externen 
Steuerrechner fest definierte Datenstrukturen austauschen muss, die zum 
größten Teil aus 8-Byte-double Feldern bestehen.
Für die interne Rechnerei würde auch 4Byte-double reichen.

Leider ist in AVR-Studio (gcc) der double- und auch der real- Typ nur 
mit 4Byte definiert. Bisher konnte ich auch keine Compilereinstellung 
finden, die 8Byte zuläßt.
Ausserdem funktioniert sprintf auf double und real mit %f nicht. Da wird 
ein ? geliefert. Hat jemand eine Ahnung was das bedeutet?

Für Tipps bezüglich 8Byte double wäre ich sehr dankbar. Gibt es 
vielleicht doch einen Compilerschalter oder einen anderen Compiler, der 
das kann?
#458655
Lesenswert?

Auch wenn das hier fuer echten double gedacht ist, kann dieser Code
als basis dienen.
1
/*
2
 * C O N V E R T   F R O M   I E E E   E X T E N D E D  
3
 */
4

5
/* 
6
 * Copyright (C) 1988-1991 Apple Computer, Inc.
7
 * All rights reserved.
8
 *
9
 * Machine-independent I/O routines for IEEE floating-point numbers.
10
 *
11
 * NaN's and infinities are converted to HUGE_VAL or HUGE, which
12
 * happens to be infinity on IEEE machines.  Unfortunately, it is
13
 * impossible to preserve NaN's in a machine-independent way.
14
 * Infinities are, however, preserved on IEEE machines.
15
 *
16
 * These routines have been tested on the following machines:
17
 *    Apple Macintosh, MPW 3.1 C compiler
18
 *    Apple Macintosh, THINK C compiler
19
 *    Silicon Graphics IRIS, MIPS compiler
20
 *    Cray X/MP and Y/MP
21
 *    Digital Equipment VAX
22
 *
23
 *
24
 * Implemented by Malcolm Slaney and Ken Turkowski.
25
 *
26
 * Malcolm Slaney contributions during 1988-1990 include big- and little-
27
 * endian file I/O, conversion to and from Motorola's extended 80-bit
28
 * floating-point format, and conversions to and from IEEE single-
29
 * precision floating-point format.
30
 *
31
 * In 1991, Ken Turkowski implemented the conversions to and from
32
 * IEEE double-precision format, added more precision to the extended
33
 * conversions, and accommodated conversions involving +/- infinity,
34
 * NaN's, and denormalized numbers.
35
 */
36

37
#ifndef HUGE_VAL
38
# define HUGE_VAL HUGE
39
#endif /*HUGE_VAL*/
40

41
# define UnsignedToFloat(u)         (((double)((long)(u - 2147483647L - 1))) + 2147483648.0)
42

43
/****************************************************************
44
 * Extended precision IEEE floating-point conversion routine.
45
 ****************************************************************/
46

47
double ConvertFromIeeeExtended(bytes)
48
unsigned char *bytes;  /* LCN */
49
{
50
    double    f;
51
    int    expon;
52
    unsigned long hiMant, loMant;
53
    
54
    expon = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
55
    hiMant    =    ((unsigned long)(bytes[2] & 0xFF) << 24)
56
            |    ((unsigned long)(bytes[3] & 0xFF) << 16)
57
            |    ((unsigned long)(bytes[4] & 0xFF) << 8)
58
            |    ((unsigned long)(bytes[5] & 0xFF));
59
    loMant    =    ((unsigned long)(bytes[6] & 0xFF) << 24)
60
            |    ((unsigned long)(bytes[7] & 0xFF) << 16)
61
            |    ((unsigned long)(bytes[8] & 0xFF) << 8)
62
            |    ((unsigned long)(bytes[9] & 0xFF));
63

64
    if (expon == 0 && hiMant == 0 && loMant == 0) {
65
        f = 0;
66
    }
67
    else {
68
        if (expon == 0x7FFF) {    /* Infinity or NaN */
69
            f = HUGE_VAL;
70
        }
71
        else {
72
            expon -= 16383;
73
            f  = ldexp(UnsignedToFloat(hiMant), expon-=31);
74
            f += ldexp(UnsignedToFloat(loMant), expon-=32);
75
        }
76
    }
77

78
    if (bytes[0] & 0x80)
79
        return -f;
80
    else
81
        return f;
82
}
Gast #458656
Lesenswert?

>die zum größten Teil aus 8-Byte-double Feldern bestehen.
du übernimmst die doch nicht etwa binär???

arbeite im AVR mit 4 Byte double und übergib es als ASCII.
>Ausserdem funktioniert sprintf auf double und real mit %f nicht.
möglicherweise hast du vergessen die floating point library zu linken.

>inen anderen Compiler, der das kann?
IAR
Persönliche Seite #458658
Lesenswert?

Das Fragezeichen wird von der schlankeren nicht-float-printf-Library 
ausgegeben; Du musst nur die fettere float-unterstützende printf-Library 
verwenden und schon geht's. Überprüfe die Linkereinstellungen bzw. die 
gelinkten Libraries.

Eine manuelle Konvertierung von double nach float müsste mit partiellem 
Kopieren der höchstwertigen Bits der Mantisse und Bitschieben des 
Exponenten möglich sein; Du solltest Dir mal die binäre Repräsentation 
der entsprechenden Formate ansehen. Natürlich ist der Wertebereich von 
float gegenüber double beschränkt, bei zu großen Exponenten musst Du Dir 
also eine sinnvolle Fehlerbehandlung einfallen lassen.
Gast #458664
Lesenswert?

@Francesco: das ist eine Konvertierung von 80Bit nach 64 Bit

aber was ist denn das?
>double ConvertFromIeeeExtended(bytes)
>unsigned char *bytes;  /* LCN */
>{
funktion Convert... gibt double zurück hat als Parameter bytes 
unbekannter Typ
in Fkt. wird lokale Variable (pointer) bytes auf char definiert
oder interpretiere ich da was falsch?
#458682
Lesenswert?

>> double ConvertFromIeeeExtended(bytes)
>> unsigned char *bytes;  /* LCN */
>> {
> funktion Convert... gibt double zurück hat als Parameter bytes
> unbekannter Typ
> in Fkt. wird lokale Variable (pointer) bytes auf char definiert
> oder interpretiere ich da was falsch?

Das ist altes K&R C

im neueren ANSI C würde es heissen:

double ConvertFromIeeeExtended( unsigned char* bytes )
{
  ...
Moderator Persönliche Seite #458732
Lesenswert?

Michael Korb wrote:

> Ich habe die Lib libprintf_flt.a unter Librarys in den
> Projekteinstellungen übernommen - keine Änderung.

AVR Studio bietet keine sehr nutzerfreundliche Bedienerführung für
diese Art Einstellung.  <Werbung>Mfile ist da besser.</Werbung>

Du musst noch -Wl,-u,vfprintf in die Optionen aufnehmen (vor allen
Bibliotheken).

>> IAR

> Was kostet das Teil?

Mehr als ein gebrauchtes Auto.  Offizielle Preise wirst du nur vom
IAR Salesdroiden deines geringsten Misstrauens erfahren.
#458782
Lesenswert?

-uvfprintf

ist eine Option

Nochmal zum Mitschreiben:
AVR Studio, Project Configuration

'Libraries' anwählen:

   libprintf_flt.a    'Add Library'
   libc.a             'Add Library'

'Custom Options' anwählen:

   Linker Options auswählen

      -uvfprintf   'Add'


'OK'

Die Reihenfolge der Libraries scheint wichtig zu sein.
Wenn man die umdreht, gehts nicht mehr.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren