Question

Je suis en train de compléter un certain nombre à sa première place décimale et, compte tenu des différentes options de MidpointRounding, qui semble bien fonctionner. Un problème se pose cependant lorsque ce nombre a sunsequent décimales qui arithmétiquement affecter l'arrondissement.

Un exemple:

Avec 0.1, 0.11..0.19 et 0.141..0.44 cela fonctionne:

Math.Round(0.1, 1) == 0.1
Math.Round(0.11, 1) == 0.1
Math.Round(0.14, 1) == 0.1
Math.Round(0.15, 1) == 0.2
Math.Round(0.141, 1) == 0.1

Mais avec 0.141..0.149 il revient toujours 0.1, bien que 0.146..0.149 devrait arrondir à 0.2:

Math.Round(0.145, 1, MidpointRounding.AwayFromZero) == 0.1
Math.Round(0.146, 1, MidpointRounding.AwayFromZero) == 0.1
Math.Round(0.146, 1, MidpointRounding.ToEven) == 0.1
Math.Round(0.146M, 1, MidpointRounding.ToEven) == 0.1M
Math.Round(0.146M, 1, MidpointRounding.AwayFromZero) == 0.1M

J'ai essayé de trouver une fonction qui résout ce problème, et il fonctionne bien pour ce cas, mais bien sûr, il échoue glamorously si vous essayez d'arrondir à-dire 0.144449 à son premier chiffre décimal (qui devrait être 0.2, mais les résultats 0.1.) (Cela ne fonctionne pas avec Math.Round () non plus.)

private double "round"(double value, int digit)
{
    // basically the old "add 0.5, then truncate to integer" trick
    double fix = 0.5D/( Math.Pow(10D, digit+1) )*( value >= 0 ? 1D : -1D );
    double fixedValue = value + fix;

    // 'truncate to integer' - shift left, round, shift right
    return Math.Round(fixedValue * Math.Pow(10D, digit)) / Math.Pow(10D, digit);
}

Je suppose une solution serait d'énumérer tous les chiffres, trouver la première valeur supérieure à 4, puis arrondir, ou bien arrondir. Problème 1: Cela semble idiot, Problème 2: Je ne sais pas comment énumérer les chiffres sans gazillion de multiplications et subtractios

.

Longue histoire courte: Quelle est la meilleure façon de le faire

Était-ce utile?

La solution

Math.Round() se comporte correctement.

Lorsque vous effectuez l'arrondi point médian standard, vous ne devez jamais regarder au-delà 1 chiffre décimal au-delà de l'endroit où vous arrondissez à. Si vous êtes arrondi au dixième près, alors vous ne devez jamais regarder au-delà du deuxième chiffre après la virgule.

L'idée avec arrondi milieu est que la moitié des entre-deux chiffres devraient arrondir et la moitié devraient arrondir vers le bas. Donc, pour les nombres compris entre 0,1 et 0,2, la moitié d'entre eux devrait arrondir à 0,1 et la moitié devrait arrondir à 0,2. Le point médian entre ces deux nombres est de 0,15, de sorte que le seuil est pour arrondir. 0,146 est inférieur à 0,15, donc il faut arrondir à 0,1.

                    Midpoint
0.10                  0.15                  0.20
 |----------------|----|---------------------|
                0.146
       <---- Rounds Down

Autres conseils

Je ne comprends pas ce que vous essayez d'accomplir ici. 0,149 arrondie à la première décimale 0,1, pas 0,2

Arrondi n'est pas un processus itératif, vous arrondissez une seule fois.

0,146 arrondi à 1 chiffre décimal 0,1.

Vous ne faites pas ceci:

0.146 --> 0.15
0.15 -->  0.2

Vous faites seulement ceci:

0.146 --> 0.1

Dans le cas contraire, les éléments suivants:

0.14444444444444446

serait aussi rond à 0,2, mais il ne fonctionne pas et ne devrait pas.

Ne pas essayer de composer les «erreurs d'arrondi. Ce qui est ce que vous essayez de faire.

0,146 devrait arrondissez à .1 si vous allez à un endroit décimal.

En arrondissant à .15, puis à nouveau à 0,2 vous êtes juste d'introduire plus d'erreur d'arrondi, pas moins.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top