Domanda

double a = 18.565
return Math.Round(a,2)

.. ritorna 18.57.
Per ogni altro numero ho provato banchiere di arrotondamento ha funzionato come previsto, ad esempio Math.round (2.565,2) ha restituito 2,56.

Ogni indizio perché e quando ciò accade? E 'error o mi sto perdendo qualcosa circa arrotondamento?

Grazie ..

È stato utile?

Soluzione

Come detto Matthew, 18,565 non possono essere rappresentati con precisione. Il valore effettivo utilizzato è 18.565000000000001278976924368180334568023681640625 (trovato utilizzando DoubleConverter ), che è chiaramente oltre la metà -modo. Ora ho la sensazione che furtivamente a volte Math.Round si considerano un valore che è effettivamente oltre il punto a metà strada, ma che è il più vicino al punto a metà strada come può essere accuratamente rappresentato, come esattamente a quel punto. Tuttavia, non ho visto alcuna documentazione che descrive le situazioni in cui che viene applicato, e chiaramente non sta accadendo in questo caso. Non vorrei fare affidamento su di esso.

Anche il valore arrotondato non è esattamente 18.57, naturalmente. In realtà è 18,57000000000000028421709430404007434844970703125.

In sostanza, se davvero, davvero a cuore che rappresenta i valori decimali con precisione, si dovrebbe utilizzare decimal. Questo non è solo in termini di Math.Round -. Va a tutti gli aspetti della gestione dei valori in virgola mobile

che non dare il giusto valore per Math.Round, naturalmente:

decimal m = 18.565m;
Console.WriteLine(Math.Round(m, 2)); // Prints 18.56

Altri suggerimenti

18,565 non può essere esattamente rappresentato come un doppio. Così, la rappresentazione binaria è leggermente superiore, in modo che arrotonda. Se si utilizza decimali:

decimal a = 18.565m;
return Math.Round(a,2)

può essere esattamente rappresentato, e non avrà questo problema.

La mia ipotesi è che i mezzi di rappresentazione FP non è in realtà un trailing 5; i pericoli di FP!

Questo funziona bene, però:

        decimal a = 18.565M; // <===== decimal
        var s = Math.Round(a, 2);

Double è un valore in virgola mobile, quindi forse se si scrive come 18,565, in realtà è qualcosa in memoria come 18,56500000000000000000000000000000001, e quindi è più che il punto medio.

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