Forum: Compiler & IDEs zum leidigen Thema double


von Michael K. (michaelkorb)


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?

von Francesco N. (franceso-)


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
}

von Wolfram (Gast)


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

von Rufus Τ. F. (rufus) Benutzerseite


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.

von Wolfram (Gast)


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?

von Karl heinz B. (kbucheg)


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 )
{
  ...

von Wolfram (Gast)


Lesenswert?

danke für die Erklärung, hatte schon so ne Ahnung...

von Michael K. (michaelkorb)


Lesenswert?

Wolfram wrote:
> möglicherweise hast du vergessen die floating point library zu linken.
Ich habe die Lib libprintf_flt.a unter Librarys in den 
Projekteinstellungen übernommen - keine Änderung.

> IAR
Was kostet das Teil?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


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.

von Michael K. (michaelkorb)


Lesenswert?

Jörg Wunsch wrote:
> Du musst noch -Wl,-u,vfprintf in die Optionen aufnehmen (vor allen
> Bibliotheken).

Compileroption oder Linkoption?

von Karl heinz B. (kbucheg)


Lesenswert?

Linker.

von Michael K. (michaelkorb)


Angehängte Dateien:

Lesenswert?

klappt nicht.
Hab mal als externes Makefile exportiert - s. Anhang.

von Karl heinz B. (kbucheg)


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.

von Michael K. (michaelkorb)


Lesenswert?

Vielen Dank, jetzt hab ichs gerafft und es funzt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.