2016-05-11 6 views
0

Während des Studiums der C-essentials aus Online-Video, teilte der Autor den Code unten, um den Unterschied zwischen Float, Doppel-und Long-Double zu finden. Ich lief dieses Programm in Eclispse läuft in 64-Bit-Windows 10 Laptop.Formatbezeichner% Lf für lange Doppel in C funktioniert nicht wie erwartet

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
puts("Floating point type usage in C:"); 

// Floating point types 
float   floatNumber; 
double   doubleNumber; 
long double  longDoubleNumber; 

// Size of floating point types 
//lu - Stands for "unsigned decimal integer" and "long" 
printf("Storage size for unsigned float : %lu bytes \n", sizeof(float)); 
printf("Storage size for double :   %lu bytes \n", sizeof(double)); 
printf("Storage size for long double : %lu bytes \n", sizeof(long double)); 

floatNumber = 2.0/3.0; 
doubleNumber = 2.0/3.0; 
longDoubleNumber = 2.0/3.0; 

puts("\nCompare precision at 4 decimal points:"); 
printf("floatNumber  = %1.4f\n", floatNumber); 
printf("doubleNumber  = %1.4lf\n", doubleNumber); 
printf("longDoubleNumber = %1.4Lf\n", longDoubleNumber); 

puts("\nCompare precision at 10 decimal points:"); 
printf("floatNumber  = %1.10f\n", floatNumber); 
printf("doubleNumber  = %1.10lf\n", doubleNumber); 
printf("longDoubleNumber = %1.10Lf\n", longDoubleNumber); 

puts("\nCompare precision at 30 decimal points:"); 
printf("floatNumber  = %1.30f\n", floatNumber); 
printf("doubleNumber  = %1.30lf\n", doubleNumber); 
printf("longDoubleNumber = %1.30g\n", longDoubleNumber); 
return 0; 
} 

Irgendwie bekomme ich nicht die erwartete Ausgabe. Ich habe die Ausgabe hinzugefügt, die ich in meiner Eclispse-Konsole erhalten hatte. Könnte mir jemand helfen, was falsch

Floating point type usage in C: 
Storage size for unsigned float : 4 bytes 
Storage size for double :   8 bytes 
Storage size for long double : 16 bytes 

Compare precision at 4 decimal points: 
floatNumber  = 0.6667 
doubleNumber  = 0.6667 
longDoubleNumber = 0.0000    //Expected value = 0.6667 

Compare precision at 10 decimal points: 
floatNumber  = 0.6666666865 
doubleNumber  = 0.6666666667 
longDoubleNumber = 0.0000000000 //Expected value = 0.6666666667 

Compare precision at 30 decimal points: 
floatNumber  = 0.666666686534881590000000000000 
doubleNumber  = 0.666666666666666630000000000000 
longDoubleNumber = 3.1728895775924853e-317 //This is not the expected value 
ging, um herauszufinden,
+2

Welche Compiler und Laufzeit/libc verwenden Sie? –

+0

Probieren Sie 'longDoubleNumber = (long double) 2.0/3.0;' – sjsam

+0

@sjsam aus, das Fehlen eines Cast im ursprünglichen Code könnte absichtlich sein. Jedenfalls erklärt es die vorgestellte Ausgabe nicht. –

Antwort

0

Ich schlage vor, Sie ein paar Korrekturen vornehmen und dann die Tests erneut ausführen. Zunächst müssen wir sicherstellen, dass alle Arten korrekt sind und keine Aktionen oder andere Dinge beteiligt sind. Wir brauchen

floatNumber = 2.0/3.0; 
longDoubleNumber = 2.0/3.0; 

zu

floatNumber = 2.0f/3.0f; 
longDoubleNumber = 2.0L/3.0L; 

Dies ist erforderlich ändern Aktionen des Ergebnisses nicht zulassen zu verdoppeln (im ersten Fall und Typumwandlung von Doppel zu langen Doppeln in Sekunden), weil orginally beide Ihre Operanden waren jeweils vom Typ "double".

Zweitens sollten Sie nicht definiertes Verhalten loszuwerden in

printf("longDoubleNumber = %1.30g\n", longDoubleNumber); 

und eine richtige lange doppelte Längenangabe in Format-String verwenden. Es wird so aussehen:

printf("longDoubleNumber = %1.30Lg\n", longDoubleNumber); 

Benachrichtigen Sie uns von den Ergebnissen.

+1

Obwohl diese Änderungen * vernünftig * sind, ist nicht klar, ob sie alle für die spezifischen Demonstrationszwecke des Programms geeignet sind. Noch wichtiger ist jedoch, dass nicht klar ist, warum diese Ihrer Meinung nach die spezifischen Probleme des OP, die vom OP festgestellt wurden, lösen würden. Selbst die letzte vorgeschlagene Änderung, die tatsächlich notwendig ist, scheint aufgrund der Art der früheren inkorrekten Ausgaben wahrscheinlich keine korrekte Ausgabe hervorzubringen. –

+0

@JohnBollinger, ich habe nicht gesagt, dass sie, ich sagte, dass sie "sollten". Ich kann jedoch zustimmen, dass das Wort "könnte" angemessener ist. Der Zweck der Änderungen besteht darin, mögliche Nebenwirkungen von Typumwandlungen zu negieren. Sobald man sagen kann, dass es keine gibt, und wenn das Problem auf die gleiche Art andauert, können wir vorwärts gehen. Das ist der vernünftigste Ansatz, den ich atm sehe. – HighPredator

+0

Selbst "Macht" ist unangemessen optimistisch. Es gibt keinen Grund zu erwarten, dass die vorgeschlagenen Änderungen die Hauptprobleme des OP lösen würden. –

Verwandte Themen