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?
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 | }
|
>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
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.
@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?
>> 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 ) { ...
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?
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.
Jörg Wunsch wrote: > Du musst noch -Wl,-u,vfprintf in die Optionen aufnehmen (vor allen > Bibliotheken). Compileroption oder Linkoption?
-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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.