VBA.VB6 - Les fonctions d'arrondi

Septembre 2016



La fonction mathématique « arrondi() » consiste à transformer un nombre précis en nombre de précision moindre. Le cas le plus courant est la transformation d'un nombre décimal en nombre entier.
La norme IEEE 754-2008 standardise les formats et les méthodes de calcul des nombres binaires et décimaux, exprimés en virgule flottante, dans les micro-processeurs et leur environnement. Elle définit 5 méthodes d'arrondi sélectionnables par l'utilisateur. Cette norme est aussi un guide pour les concepteurs de langage afin d'assurer leur portabilité, mais elle n'est pas imposée, d'où la grande disparité des résultats de la fonction Round() selon les langages.

Voici une douzaine de méthodes mathématiques pour arrondir un nombre :


On qualifie aussi les arrondis de symétriques ou asymétriques (par rapport à zéro).

D'autres dénominations sont souvent employées pour ces arrondis mais la plupart sont imprécises, voire ambigües et donc, elles font l'objet de différentes interprétations.

Exemples


Les arrondis au plus près

L'arrondi au plus prés est le plus intuitif des arrondis. Par exemple les valeurs 3.1, 3.2, 3.3, et 3.4 sont arrondies vers le bas à 3, tandis que les valeurs 3,6, 3,7, 3,8, et 3,9 sont arrondies, mais pour 3.5 les deux choix sont possibles (3 ou 4).

Les différentes méthodes d'arrondi au plus près se distinguent par la façon d'arrondir la valeur médiane située exactement à mi-chemin entre le nombre arrondi supérieur et le nombre arrondi inférieur.

Arrondi au pair le plus près (ou arrondi bancaire)

Cette méthode « round ties to even» est le mode d'arrondi par défaut de la norme IEEE 754-2008. Elle doit être utilisée pour nombres au format binaire. Avec cette méthode d'arrondi au pair le plus prés, la valeur médiane est arrondie vers le chiffre pair.

Par exemple : 2.5 à 2 et 3.5 à 4.

Cet arrondi symétrique permet de réduire le biais cumulatif qui peut résulter d'un arrondi toujours dans le même sens (cf. arrondis vers l'infini positif, vers l'infini négatif, vers zéro, arithmétique), mais un biais apparait lorsqu'on utilise uniquement des nombres pairs ou des nombres impairs.

Fonction

C'est la fonction Round()du VB, ainsi que du C#, et les résultats pouvant paraitre surprenants non sont pas issus d'un bug.

Arrondi arithmétique

L'arrondi arithmétique [symétrique] « round ties to away» est préconisé par la norme IEEE 754-2008 pour nombres au format décimal.

Cette méthode est la plus connue, c'est celle que nous avons appris en cours de mathématiques, celle des tableurs (Excel, Calc, ...). Il s'agit d'une des méthodes d'arrondi au plus près pour laquelle la valeur médiane est toujours arrondie au chiffre supérieur.

Par exemple : 3.5 à 4 et -3.5 à -4.

Cette méthode peut introduire un biais cumulatif mais elle limite l'accumulation des erreurs lors de calculs successifs.

Fonction :

Public Function ArrondiArithmetique(ByVal Nombre, Optional ByVal Decimales = 0)

' Fonction Arrondi arithmétique [symétrique] : au plus prés, 0.5 vers les infinis

  ArrondiArithmetique = Fix(Nombre * 10 ^ Decimales + Sgn(Nombre) * 1 / 2) / 10 ^ Decimales

End Function

Arrondi vers l'infini positif

Cette méthode correspond à « Round toward positive » défini par la norme IEEE 754-2008.

Il s'agit d'un arrondi asymétrique. Dans le cas d'un nombre positif, le résultat reste inchangé si les chiffres à éliminer sont tous nuls; sinon le dernier chiffre est arrondi au chiffre supérieur. Dans le cas d'un nombre négatif, les chiffres à éliminer sont simplement supprimés.

Par exemple : 3.1 à 4 et -3.9 à -3.

Cette méthode se traduit par un biais cumulatif positif et de plus, elle est rarement utilisée dans les implémentations matérielles car sa réalisation est plus onéreuse.

Fonction :

Public Function ArrondiVersPlusInfini(ByVal Nombre, Optional ByVal Decimales = 0)

' Fonction Arrondi vers + l'infini

  ArrondiVersPlusInfini = (Int(Nombre * 10 ^ Decimales) _

    + IIf(Nombre = Int(Nombre * 10 ^ Decimales), 0, 1)) / 10 ^ Decimales

End Function

Arrondi vers l'infini négatif

Cette méthode correspond à « Round toward negative » défini par la norme IEEE 754-2008.

Il s'agit d'un arrondi asymétrique. Dans le cas d'un nombre positif, les chiffres à éliminer sont simplement supprimés. Dans le cas d'un nombre négatif, le résultat reste inchangé si les chiffres à éliminer sont tous nuls; sinon le dernier chiffre est arrondi au chiffre supérieur.

Par exemple : 3.9 à 3 et -3.1 à -4.

Cette méthode, simple à réaliser matériellement, se traduit par un biais cumulatif négatif.

Fonction :

Public Function ArrondiVersMoinsInfini(ByVal Nombre, Optional ByVal Decimales = 0)

' Fonction Arrondi vers - l'infini

  ArrondiVersMoinsInfini = Int(Nombre * 10 ^ Decimales) / 10 ^ Decimales

End Function

Arrondi vers zéro

Cette méthode, « Round toward zero » définie par la norme IEEE 754-2008 est aussi appelée troncature : les chiffres à éliminer sont simplement supprimés, c'est un arrondi symétrique.

Par exemple : 3.9 à 3 et -3.9 à -3.

Cette méthode correspond à la fonction ARRONDI.INF() des tableurs (Excel, Calc, ...).

Fonction :

Public Function ArrondiVersZero(ByVal Nombre, Optional ByVal Decimales = 0)

' Fonction arrondi vers zéro ; au chiffre inférieur (troncature)

  ArrondiVersZero = Fix(Nombre * 10 ^ Decimales) / 10 ^ Decimales

End Function

Arrondi arithmétique asymétrique

Il s'agit d'une des méthodes d'arrondi au plus près pour laquelle la valeur médiane est toujours arrondie vers l'infini positif. Elle correspond à la fonction Round de la bibliothèque Math du Java.

Par exemple 3.5 à 4 et -3.5 à -3.

Cette méthode se traduit par un biais cumulatif positif.

Fonction :

Public Function ArrondiArithmetiqueAsymetrique(ByVal Nombre, Optional ByVal Decimales = 0)

' Fonction Arrondi arithmétique asymétrique : au plus prés, 0.5 vers + l'infini

  ArrondiArithmetiqueAsymetrique = Int(Nombre * 10 ^ Decimales + 1 / 2) / 10 ^ Decimales

End Function

Arrondi au plus près vers l'infini négatif

Il s'agit d'une des méthodes d'arrondi au plus près asymétrique pour laquelle la valeur médiane est toujours arrondie vers l'infini négatif.

Par exemple : 3.5 à 3 et -3.5 à -4.

Cette méthode se traduit par un biais cumulatif négatif.

Fonction :

Public Function ArrondiPlusPresVersMoinsInfini(ByVal Nombre, Optional ByVal Decimales = 0)

' Fonction Arrondi au plus prés vers le bas : au plus prés, 0.5 vers - l'infini

  ArrondiPlusPresVersMoinsInfini = (Fix(Nombre * 10 ^ Decimales + Sgn(Nombre) * 1 / 2) _

    - IIf(Nombre * 10 ^ Decimales - Fix(Nombre * 10 ^ Decimales) = 1 / 2, Sgn(Nombre), 0)) _

    / 10 ^ Decimales

End Function

Arrondi au plus près vers zéro

Il s'agit d'une des méthodes d'arrondi au plus près symétrique pour laquelle la valeur médiane est toujours arrondie vers zéro

Par exemple : 3.5 à 3 et -3.5 à -3).

Cette méthode est parfois appelée « arrondi gaussien » parce qu'elle fournit une distribution symétrique par rapport à sa valeur moyenne.

Fonction :

Public Function ArrondiPlusPresVersZero(ByVal Nombre, Optional ByVal Decimales = 0)

' Fonction Arrondi au plus prés vers zero : au plus prés, 0.5 vers zéro

  ArrondiPlusPresVersZero = (Fix(Nombre * 10 ^ Decimales + Sgn(Nombre) * 1 / 2) _

    - IIf(Nombre * 10 ^ Decimales - Fix(Nombre * 10 ^ Decimales) = _

    Sgn(Nombre) * 1 / 2, Sgn(Nombre), 0)) / 10 ^ Decimales

End Function

Arrondi à l'impair le plus près

Il s'agit d'une des méthodes d'arrondi au plus près symétrique très rarement utilisée, pour laquelle la valeur médiane est toujours arrondie vers le chiffre impair.

Par exemple : 3.5 à 3 et 4.5 à 5

Ses avantages sont théoriquement équivalents à ceux de l'arrondi au pair le plus prés, mais l'arrondi à l'impair le plus près présente l'inconvénient de jamais arrondir à zéro.

Fonction :

Public Function ArrondiPlusPresImpair(ByVal Nombre, Optional ByVal Decimales = 0)

' Fonction Arrondi à l'impair le plus prés : au plus près, 0.5 vers l'impair

  ArrondiPlusPresImpair = (Fix(Nombre * 10 ^ Decimales + Sgn(Nombre) * 1 / 2) _

    - IIf(Nombre * 10 ^ Decimales - Int(Nombre * 10 ^ Decimales) <> 1 / 2, 0, _

    IIf(Fix(Nombre * 10 ^ Decimales + Sgn(Nombre) * 1 / 2) / 2 = _

    Int(Fix(Nombre * 10 ^ Decimales + Sgn(Nombre) * 1 / 2) / 2), Sgn(Nombre), 0))) _

    / 10 ^ Decimales

End Function

Arrondi vers les infinis

Il s'agit d'une méthode d'arrondi symétrique. Le résultat reste inchangé si les chiffres à éliminer sont tous nuls; sinon le dernier chiffre est arrondi au chiffre supérieur.

Par exemple : 3.1 à 4 et -3.1 à -4.

Cette méthode correspond à la fonction ARRONDI.SUP() des tableurs (Excel, Calc, ...),

Fonction :

Public Function ArrondiVersInfinis(ByVal Nombre, Optional ByVal Decimales = 0)

' Fonction Arrondi vers les infinis : au chiffre supérieur

  ArrondiVersInfinis = (Fix(Nombre * 10 ^ Decimales) _

    + IIf(Nombre = Fix(Nombre * 10 ^ Decimales), 0, Sgn(Nombre))) / 10 ^ Decimales

End Function

Arrondi stochastique

Il s'agit d'une des méthodes d'arrondi au plus près, utilisée en statistiques, pour laquelle la valeur médiane est arrondie de façon aléatoire ou pseudo-aléatoire vers l'infini positif ou l'infini négatif.

Par exemple : 3.5 arrondi aléatoirement à 3 ou à 4

L'arrondi stochastique permet de réduire le biais cumulatif qui peut résulter des autres méthodes d'arrondi, mais son caractère aléatoire rend quasi impossible la réplication des résultats.

Fonction :

Public Function ArrondiStochastique(ByVal Nombre, Optional ByVal Decimales = 0)

' Avant l'appel de la fonction, il faut exécuter Randomize dans le code appelant.

' Fonction Arrondi stochastique : au plus près, 0.5 aléatoire vers le haut ou vers le bas

  ArrondiStochastique = (Fix(Nombre * 10 ^ Decimales + Sgn(Nombre) * 1 / 2) _

    - IIf(Nombre * 10 ^ Decimales - Int(Nombre * 10 ^ Decimales) <> 1 / 2, 0, _

    Int(Rnd * 2) * Sgn(Nombre))) / 10 ^ Decimales

End Function

Arrondi alterné

Il s'agit d'une des méthodes d'arrondi au plus près, utilisée en statistiques, pour laquelle la valeur médiane est arrondie de façon alternée vers l'infini positif puis vers l'infini négatif (ou inversement).

Par exemple : 3.5 à 4 puis 2.5 à 2 ou encore 2.5 à 3 puis 3.5 à 3

L'arrondi alterné permet de réduire le biais cumulatif qui peut résulter des autres méthodes d'arrondi, et contrairement à l'arrondi stochastique, la réplication des résultats est souvent possible.

Fonction :

Public Function ArrondiAlterne(ByVal Nombre, Optional ByVal Decimales = 0)

Static flgDown As Boolean

' Fonction Arrondi alterné : au plus près, 0.5 alterné vers le haut et vers le bas

  If Nombre * 10 ^ Decimales - Int(Nombre * 10 ^ Decimales) = 1 / 2 Then

    ArrondiAlterne = IIf(flgDown Xor Sgn(Nombre) = -1, Sgn(Nombre), 0)

    flgDown = Not flgDown

  End If

  ArrondiAlterne = (Fix(Nombre * 10 ^ Decimales + Sgn(Nombre) * 1 / 2) - ArrondiAlterne) _

                   / 10 ^ Decimales

End Function


Texte quasi intégral de Patrice33470

mots clés: arrondi Round Round() VB bug

A voir également :

Ce document intitulé «  VBA.VB6 - Les fonctions d'arrondi  » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.