2016-11-25 1 views
0

Ich versuche Maxwell-Boltzmann-Verteilung zu berechnen, aber dieser Code gibt 0,00000, was ist das Problem?Maxwell-Boltzmann-Verteilung berechnen

#include<stdio.h> 
#include<stdlib.h> 
#include<math.h> 
int main() 
{ 

    float e=2.718228183, pi=3.14159265, m=2.66*pow(10,-23), t, k=1.38*pow(10,-23), v, result; 

    scanf("%f %f", &t, &v); 

    result = sqrt(pow(m/(2*pi*k*t), 3)) * 4 * pi * pow(v,2) * pow(e, -(m * pow(v,2))/(2*k*t)); 

    printf("%f", result); 
} 
+4

Der Code gibt '0.000000' für * was * Eingabewerte? –

+0

gibt jetzt nur 0 @SvenMarnach – user6200763

+0

zum Beispiel 500 100 @WeatherVane – user6200763

Antwort

2

Wie in den Kommentaren beschrieben, die Verwendung von float zusammen mit der reduzierten Genauigkeit der Konstanten gibt ein Ergebnis, das nicht mehr als float darstellbaren wird. Wenn Sie den Datentyp auf double umstellen, erhalten Sie zwei Dezimalstellen der Genauigkeit. Wenn wir exp, mehr Ziffern für Pi und ein bisschen Rekombination der Berechnungen verwenden, erhalten wir 12 Genauigkeitsziffern. Z.B .:

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
int main() 
{ 

    double pi = 3.1415926535897932384626433832795028842, m = 2.66e-23, k = 
     1.38e-23; 
    double t, v, v2, dkt, result; 
    // check omitted 
    scanf("%lf %lf", &t, &v); 

    v2 = v * v; 
    dkt = 2 * k * t; 

    result = pow(m/(pi * dkt), 3/2.0) * 4 * pi * v2 * exp(-(m * v2)/(dkt)); 
    printf("%.20g\n", result); 
    return 0; 
} 

Das Ergebnis aus Pari/GP ist 8.1246636077915008261803395870165527173e-9 und das Ergebnis, das wir oben mit dem Code erhalten, ist 8.1246636077914841125e-09. Ohne die Zwischenergebnisse v2, dkt und den Ersatz von sqrt haben wir 8.1246636077914824582e-09, keinen großen Unterschied, vor allem mit Genauigkeit, wo es nichts gewonnen hat.

Wenn Sie die vollen 16 Dezimalstellen der Genauigkeit möchten, müssen Sie das Ganze auseinander nehmen und einen anderen Ansatz wählen.

+0

Der eigentliche Fehler in Ihrem Code ist zufällig. Mit 'printf ("% e ", result);' berechnet der OP-Code '8.127763e-09'. Die anderen Änderungen sind meist Flaum ... – EOF

+0

@EOF der obige Code ist nicht als Fix gedacht, wie aus dem letzten Satz hervorgeht. Zumindest dachte ich, der letzte Satz würde deutlich machen, dass es keine sofortige Lösung gibt, nur mit einem ganz anderen Ansatz. Ein Doppel-Doppel (das 112-Bit Doppel-Doppel) könnte es für einen begrenzten, aber wahrscheinlich ausreichend großen Bereich tun, aber ich habe keine vollständige Analyse der Berechnung durchgeführt. Das 'exp' und' pow (x, y) '(=' exp (y log x) ') würde eine Reihe und eine Minimax Poly für sie mit Remez oder ähnlichem gefunden vorschlagen (zB mit Hilfe von http: // lolengine .net/wiki/oss/lolremez). – deamentiaemundi

+0

Der OP-Fehler ist * wahrscheinlich * nicht, dass die n-te Dezimalziffer falsch ist. Das Problem des OP bestand darin, dass das Ergebnis * völlig nutzlos * war aufgrund der Idiotie von '% f' als 'printf()' - Konvertierungsspezifizierer. – EOF

0

ersetzen

double pi=acos(-1.); 

statt

double pi=3.1415926535897932384626433832795028842;