Frage

1) Ist das unoverflowable?

long long v1, v2, result;
[..]
result = ((long double) v1 / v2) * 1000000LL;

1.a) Kann ich die LL auf der konstanten auslassen? Und warum.

2) Alternativ ist diese Variante ohne Schwimmer ok?

long long l1, l2, result;
[..]
result = (1000000 * (v1 / v2) + v1 % v2);

2.a), die mehr Gemeinkosten hat? Das erste oder dieses Beispiel?

3) schwimmt immer Überlauf, oder wickeln Sie einfach auf ‚vernünftige‘ Werte?

War es hilfreich?

Lösung

Ja, das Ergebnis in Beispiel (1) könnte leicht überlaufen, wenn, sagen wir, v1 = 1000000000000000 und v2 = 1. Sie brauchen nicht auf die LL auf dieser konstant, weil es klein genug ist, in eine int passen (unter den meisten Implementierungen, in jedem Fall).

(2) Das kann überlaufen ebenso wie Beispiel 1, wenn v1 und v2 sind als ich ihnen gegeben habe.

Das erste Beispiel ist teurer als Gleitkommaarithmetik ist teurer als Integer-Arithmetik.

(3) Floats kann sicherlich Überlauf und die Folgen sind abhängig von der Implementierung.

Wie Arjit ausgeführt hat, können Sie einen Überlauf verhindern, indem der Wert von v1 zu prüfen, bevor die Berechnung durchgeführt wird. Wenn v1 negativ sein könnte, würde man auch die negative Version überprüfen müssen, und vielleicht könnte das folgende besser ...

if ((LONG_LONG_MAX / 1000000) > V1)
{
...
}

Wenn Sie wirklich gegen die Grenze sind, könnten Sie sich selbst ein wenig mehr Spielraum durch die Variablen deklarieren unsigned sein.

Later - bearbeiten, um eine korrekte Fehler hingewiesen durch Arjit

.

Andere Tipps

Zum einen

  1. wenn tun INT oder Lang Berechnung Schwimmer es beinhalten dont. Weil Ihr Ergebnis im ersten Teil viele unterschiedliche Werte aufweisen würden, die nahezu gleich.

Weil (float) v1 / v2 = ab.cdef. // wo cdef kann variieren.

Ihre zweite Implementierung kann auch dazu führen, Überlauf wenn v1 = 2 ^ 15 und V 2 = 1

Wenn Sie also für Überlauf und Sicherheit suchen, sollten Sie immer überprüfen

wie 2 ^ 18/1000000 Konstante, die in diesem Fall

so

if(2^18/Constant > v1)

    result = (1000000 * (v1 / v2) + v1 % v2);

Dies wäre jeder Hack Beweis.

Hope Dies hilft

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top