Domanda

1) È questo unoverflowable?

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

1.a) Posso lasciare fuori il LL sulla costante? E perché.

2) In alternativa è questa variazione senza un ok galleggiante?

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

2.a) che ha più le spese generali? Il 1 ° o questo esempio?

3) Can galleggia sempre troppo pieno, o semplicemente avvolgere di valori 'sane'?

È stato utile?

Soluzione

Sì, il risultato nell'esempio (1) potrebbero facilmente traboccare se, per esempio, v1 = 1.000.000 miliardi e v2 = 1. Non hanno bisogno della LL su quel costante, perché è abbastanza piccolo per adattarsi in un int (sotto la maggior parte implementazioni, in ogni caso).

(2) che possono traboccare altrettanto bene come ad esempio 1 se v1 e v2 sono come le ho dato.

Il primo esempio è più costose, come aritmetica in virgola mobile è più costoso di aritmetica intera.

(3) Galleggianti può certamente troppo pieno e le conseguenze sono a carico di attuazione.

Come Arjit ha fatto notare, è possibile impedire un overflow controllando il valore di V1 prima di eseguire il calcolo. Se v1 potrebbe essere negativo si avrebbe inoltre necessario verificare la versione negativa, e forse la seguente potrebbe essere meglio ...

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

Se siete veramente contro il limite si potrebbe dare voi stessi un po 'più spazio dichiarando le variabili da unsigned.

In seguito - Modifica per correggere errori sottolineato da Arjit

.

Altri suggerimenti

In primo luogo

  1. se facendo INT o Long calcolo dont coinvolgere galleggiante ad esso. Perché il tuo risultato nella prima parte avrebbe molti valori diversi che sono quasi uguali.

Poiché (float) v1 / v2 = ab.cdef. // dove CDEF può variare.

Il tuo secondo implementazione può anche causare troppo pieno se v1 = 2 ^ 15 e v2 = 1

quindi, se siete alla ricerca di troppo pieno e la sicurezza si dovrebbe sempre verificare

come 2 ^ 18 / costante che è 1000000 in questo caso

così

if(2^18/Constant > v1)

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

Questo sarebbe alcuna prova hack.

Spero che questo aiuti

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top