Modulo falsch Berechnung?
-
So, wie schon @Finnegan geschrieben hat, mit rationalen Zahlen.
Laut NTSC-Film entspricht dies (bzw. ), d.h.const int64_t ms_per_s = 1000; int64_t time_in_milliseconds = frames * ms_per_s * 1001 / 24000;
frames
sollte dabei aber auch schon eine rationale Zahl sein (bzw. in so eine umgewandelt werden können) - darum hatte ich dich ja auch schon gefragt woher der Wert fürd
(alsoframes
, wie wir jetzt wissen) kommt?
Du könntest dafür z.B. die Boost-Library Rational Numbers benutzen.Für
frames = 5006398.17
(bzw.frames = Rational(500639817, 100)
) sollte (wenn der Windows-Rechner sich nicht verrechnet hat) abgerundettime_in_milliseconds = 208808523
(bzw.58h 0m 8s 523ms
herauskommen).
-
@Th69 sagte in Modulo falsch Berechnung?:
int64_t
ja das Problem ist auch noch das es im NTSC-FILM 2 verschiedene Formate gibt einmal 24.0fps und einmal 23,976fps - das muss erstmal unterschieden werden. Deshalb ist alles ersteinmal hinfällig was dieses Format betrifft. Das heißt 23,97 ist schon falsch von dem ich ausgegangen bin. Dein Beispiel ist gut ich guck mir das mal genauer an. Aber ich werde sehr wahrscheinlich mit diesem 23,976fps und nicht mit (24000/1001) und dann zusätzlich halt 24.00fps was ja einfach ist arbeiten.
So hab erstmal auf 23,976 umgeschrieben, selber hatte ich damit nie zu tun nur eben mit PAL-Zeiten deshalb kann ich es nicht überprüfen. Herauskommen sollte beim Ergebniss eigentlich 58:01:01:000 - wenn 23,976fps zugrunde liegen. Der Frame-Wert dafür liegt bei 5007651.336.
NTSC 29,97 / NTSC FILM 23,976 = 1.25.
6259564.17/ 5007651.336 = 1.25. (TimeCode 58:01:01:000)Update: Habe mir mal Deine Berechnung reingezogen, irgendwas stimmt da nicht.
Komme damit nicht klar die Ergebnisse sind komplett daneben.
-
Da du anscheinend das RAD Studio (
AnsiString
undShowMessage
), also den Embarcadero-Compiler, benutzt, könntest du auch den Datentyp System.Currency verwenden - dieser hat exakt 4 Nachkommastellen (ist dem Namen nach eigentlich für Währungen gedacht, aber auch für andere Anwendungsfälle, wie deinem, geeignet).
-
@Th69 also bei NTSC 23.976 benötige ich maximal 6 Nachkommastellen.
86313599.976024 = 999:59:59:999 h/m/s/msDafür reicht dann aber int nicht mehr aus.
-
Ich schrieb ja auch
int64_t
.Und für Fixpoint-Arithmetics habe ich auch noch Compositional Numeric Library (CNL) gefunden (dort kannst du dann die Anzahl der max. Nachkommastellen explizit angeben).
Auch wenn ich nicht verstehe, warum du bei Millisekunden-Genauigkeit mehr als 3 Nachkommastellen benötigst.
-
@Th69 Es geht auch mit 3 nur muss ich dann aufrunden.
-
@Th69 sagte in Modulo falsch Berechnung?:
int64_t time_in_milliseconds = frames * ms_per_s * 1001 / 24000;
Es ist besser, das ein wenig umzustellen:
int64_t time_in_milliseconds = (int64_t) (1001.0 / 24000.0 * frames * ms_per_s);
wobei es auch hierbei Ungenauigkeiten gibt:
*
und sogar/
sind in diesem Fall Ungenauigkeitsbehaftet.
-
@Gestalt sagte in Modulo falsch Berechnung?:
Ich finde das nicht gut das man nach dem Sinn gefragt wird nur weil ich Dinge mache die eine anderer nicht macht und er deshalb darin keinen Sinn sieht.
Falls du es noch nicht mitbekommen haben solltest: Hier wird im Allgemeinen nicht nach dem "warum" gefragt, um jemanden auszulachen, sondern um besser helfen zu können.
-
@Finnegan sagte in Modulo falsch Berechnung?:
ch dem "warum" ge
Ich weiß wie Menschen sind, hatte mein ganzes leben lang Zeit sie zu analysieren mir brauch keiner was von alle sind so lieb erzählen. Es gibt Ausnahmen die sind aber wirklich selten.
-
@noLust sagte in Modulo falsch Berechnung?:
@Th69 sagte in Modulo falsch Berechnung?:
int64_t time_in_milliseconds = frames * ms_per_s * 1001 / 24000;
Es ist besser, das ein wenig umzustellen:
int64_t time_in_milliseconds = (int64_t) (1001.0 / 24000.0 * frames * ms_per_s);
wobei es auch hierbei Ungenauigkeiten gibt:
*
und sogar/
sind in diesem Fall Ungenauigkeitsbehaftet.Und was ist daran nun "besser"? Die Integer-Berechnung war immer auf volle, "abgelaufene" Millisekunden genau, egal wie viele Frames man hat (Fehler 1ms). mit diesen
double
kann der Fehler jetzt abhängig von (großem)frames
nahezu beliebig groß werden.
-
int64_t time_in_milliseconds = (int64_t) (1001.0 / 24000.0 * 47.952 * 1000); //muss sein 2000 ist aber 1999
also so gehts nicht, weil das "47.952" 2sekunden bzw. 2000ms sind
da bleib ich doch liebers bei meiner Variante.
-
@Finnegan Ich hab da auch noch ein
round
vergessen@Gestalt sagte in Modulo falsch Berechnung?:
Es gibt Ausnahmen die sind aber wirklich selten.
Na ja, irgendwie kaufe ich dir die Unschuldslammnummer auch nicht so ganz ab.
-
@noLust naja ich weiß nicht nicht wie ich sagen soll aber ich bin nicht wie ihr, ich hab mit dem allem was sich da als Menschen bezeichnen nix gemeinsames, und das ist auch gut so.
-
int64_t time_in_milliseconds = (int64_t) round((1001.0 / 24000.0 * 47.952 * 1000)); //muss sein 2000 if(time_in_milliseconds == 2000) cout << "it's true" <<endl;
-
Sag ich doch auch ... ich bin der beste.
-
@noLust nicht schlecht
-
Aber sogar ich musste gerade googeln, ob man das groß- bzw. kleinschreibt ...
Ich bin der Beste - ist richtig. Der Duden drückt sich da aber widersprüchlich aus, so ist:
- dieser Wein ist der beste
- er ist der Beste in der Klasse
beides richtig. Ich möchte gar nicht wissen, wer das wieder verbockt hat.
Edit: Na klar, Ersteres bezieht sich nur auf alle Weine - aber man möchte ja ausdrücken, dass man absolut der Beste ist, also ohne eine Einschränkung der Menge.
-
@noLust aber ich muss Dich da enttäuschen ist wahrscheinlich falsch gerundet denn
int64_t time_in_milliseconds = (int64_t) round((1001.0 / 24000.0 * 47.951* 1000)); //muss sein 1999 ist aber 2000
-
-
@Gestalt Schau hier mal nach: https://en.cppreference.com/w/cpp/numeric/math/floor