Note
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier les répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de changer de répertoire.
Cette page répertorie certains problèmes courants qui peuvent se produire lorsque vous effectuez des opérations sur des types de données intrinsèques.
les expressions Floating-Point ne sont pas comparées comme égales
Lorsque vous travaillez avec des nombres à virgule flottante (type de données unique et type de données double), n’oubliez pas qu’ils sont stockés sous forme de fractions binaires. Cela signifie qu’ils ne peuvent pas contenir une représentation exacte de n’importe quelle quantité qui n’est pas une fraction binaire (de la forme k / (2 ^ n) où k et n sont des entiers). Par exemple, 0,5 (= 1/2) et 0,3125 (= 5/16) peuvent être considérés comme des valeurs précises, alors que 0,2 (= 1/5) et 0,3 (= 3/10) ne peuvent être que des approximations.
En raison de cette imprécision, vous ne pouvez pas compter sur des résultats exacts lorsque vous utilisez des valeurs à virgule flottante. En particulier, deux valeurs théoriquement égales peuvent avoir des représentations légèrement différentes.
| Pour comparer les quantités à virgule flottante |
|---|
| 1. Calculez la valeur absolue de leur différence à l’aide de la Abs méthode de la Math classe dans l’espace System de noms. 2. Déterminez une différence maximale acceptable, de sorte que vous pouvez considérer que les deux quantités doivent être égales à des fins pratiques si leur différence n’est pas plus grande. 3. Comparez la valeur absolue de la différence à la différence acceptable. |
L’exemple suivant illustre à la fois une comparaison incorrecte et correcte de deux Double valeurs.
Dim oneThird As Double = 1.0 / 3.0
Dim pointThrees As Double = 0.333333333333333
' The following comparison does not indicate equality.
Dim exactlyEqual As Boolean = (oneThird = pointThrees)
' The following comparison indicates equality.
Dim closeEnough As Double = 0.000000000000001
Dim absoluteDifference As Double = Math.Abs(oneThird - pointThrees)
Dim practicallyEqual As Boolean = (absoluteDifference < closeEnough)
MsgBox("1.0 / 3.0 is represented as " & oneThird.ToString("G17") &
vbCrLf & "0.333333333333333 is represented as " &
pointThrees.ToString("G17") &
vbCrLf & "Exact comparison generates " & CStr(exactlyEqual) &
vbCrLf & "Acceptable difference comparison generates " &
CStr(practicallyEqual))
L’exemple précédent utilise la ToString méthode de la Double structure afin qu’elle puisse spécifier une meilleure précision que le CStr mot clé utilise. La valeur par défaut est de 15 chiffres, mais le format « G17 » l’étend à 17 chiffres.
L’opérateur Mod ne retourne pas de résultat précis
En raison de l’imprécision du stockage à virgule flottante, l’opérateur Mod peut retourner un résultat inattendu lorsque au moins l’un des opérandes est à virgule flottante.
Le type de données décimal n’utilise pas de représentation à virgule flottante. De nombreux nombres qui sont incorrects et SingleDouble sont exacts dans Decimal (par exemple 0,2 et 0,3). Bien que l’arithmétique soit plus Decimal lent qu’en virgule flottante, il peut être utile de réduire les performances pour obtenir une meilleure précision.
| Pour rechercher le reste entier de quantités à virgule flottante |
|---|
1. Déclarez des variables en tant que Decimal.2. Utilisez le caractère D de type littéral pour forcer les littéraux à Decimal, si leurs valeurs sont trop volumineuses pour le Long type de données. |
L’exemple suivant illustre l’imprécision potentielle des opérandes à virgule flottante.
Dim two As Double = 2.0
Dim zeroPointTwo As Double = 0.2
Dim quotient As Double = two / zeroPointTwo
Dim doubleRemainder As Double = two Mod zeroPointTwo
MsgBox("2.0 is represented as " & two.ToString("G17") &
vbCrLf & "0.2 is represented as " & zeroPointTwo.ToString("G17") &
vbCrLf & "2.0 / 0.2 generates " & quotient.ToString("G17") &
vbCrLf & "2.0 Mod 0.2 generates " &
doubleRemainder.ToString("G17"))
Dim decimalRemainder As Decimal = 2D Mod 0.2D
MsgBox("2.0D Mod 0.2D generates " & CStr(decimalRemainder))
L’exemple précédent utilise la ToString méthode de la Double structure afin qu’elle puisse spécifier une meilleure précision que le CStr mot clé utilise. La valeur par défaut est de 15 chiffres, mais le format « G17 » l’étend à 17 chiffres.
Comme zeroPointTwo c’est Doublele cas, sa valeur pour 0.2 est une fraction binaire répétée infiniment avec une valeur stockée de 0,2000000000000000000001. La division de 2,0 par cette quantité produit 9,999999999999999995 avec un reste de 0,19999999999991.
Dans l’expression pour decimalRemainder, le caractère D de type littéral force les deux opérandes à Decimal, et 0.2 a une représentation précise. Par conséquent, l’opérateur Mod génère le reste attendu de 0,0.
Notez qu’il n’est pas suffisant de déclarer decimalRemainder en tant que Decimal. Vous devez également forcer les littéraux à Decimal, ou ils utilisent Double par défaut et decimalRemainder reçoit la même valeur inexacte que doubleRemainder.
Le type booléen ne se convertit pas en type numérique avec précision
Les valeurs de type de données booléennes ne sont pas stockées en tant que nombres et les valeurs stockées ne sont pas destinées à être équivalentes aux nombres. Pour la compatibilité avec les versions antérieures, Visual Basic fournit des mots clés de conversion (opérateur CType, CBool, CIntet ainsi de suite) pour convertir entre Boolean les types numériques. Toutefois, d’autres langages effectuent parfois ces conversions différemment, comme les méthodes .NET Framework.
Vous ne devez jamais écrire de code qui s’appuie sur des valeurs numériques équivalentes pour True et False. Dans la mesure du possible, vous devez limiter l’utilisation des Boolean variables aux valeurs logiques pour lesquelles elles sont conçues. Si vous devez combiner et chiffrer Boolean des valeurs, vérifiez que vous comprenez la méthode de conversion que vous sélectionnez.
Conversion en Visual Basic
Lorsque vous utilisez les CType mots clés ou CBool les mots clés de conversion pour convertir des types de données numériques en Boolean, 0 devient False et toutes les autres valeurs deviennent True. Lorsque vous convertissez Boolean des valeurs en types numériques à l’aide des mots clés de conversion, False devient 0 et True -1.
Conversion dans l’infrastructure
La ToInt32 méthode de la classe dans l’espace ConvertSystem de noms se True convertit en +1.
Si vous devez convertir une Boolean valeur en type de données numérique, faites attention à la méthode de conversion que vous utilisez.
Le littéral de caractère génère une erreur du compilateur
En l’absence de caractères de type, Visual Basic suppose les types de données par défaut pour les littéraux. Le type par défaut d’un littéral de caractère placé entre guillemets (" ") est String.
Le String type de données n’est pas étendu au type de données char. Cela signifie que si vous souhaitez affecter un littéral à une Char variable, vous devez effectuer une conversion étroite ou forcer le littéral au Char type.
| Pour créer un littéral Char à affecter à une variable ou à une constante |
|---|
1. Déclarez la variable ou la constante en tant que Char.2. Placez la valeur du caractère entre guillemets ( " ").3. Suivez les guillemets doubles fermants avec le caractère C de type littéral pour forcer le littéral à Char. Cela est nécessaire si le commutateur de vérification de type (Instruction Option Strict) est On, et il est souhaitable dans tous les cas. |
L’exemple suivant illustre les affectations infructueuses et réussies d’un littéral à une Char variable.
Dim charVar As Char
' The following statement attempts to convert a String literal to Char.
' Because Option Strict is On, it generates a compiler error.
charVar = "Z"
' The following statement succeeds because it specifies a Char literal.
charVar = "Z"c
' The following statement succeeds because it converts String to Char.
charVar = CChar("Z")
Il existe toujours un risque d’utilisation de conversions restrictives, car elles peuvent échouer au moment de l’exécution. Par exemple, une conversion de String vers Char peut échouer si la String valeur contient plusieurs caractères. Par conséquent, il est préférable de programmer pour utiliser le caractère de C type.
Échec de la conversion de chaîne au moment de l’exécution
Le type de données string participe à très peu de conversions étendues.
String s’élargit uniquement à lui-même et Objectuniquement Char et Char() (un Char tableau) à String. Cela est dû au fait que String les variables et les constantes peuvent contenir des valeurs que d’autres types de données ne peuvent pas contenir.
Lorsque le commutateur de vérification de type (Instruction Option Strict) est On, le compilateur interdit toutes les conversions restrictives implicites. Cela inclut ceux impliquant String. Votre code peut toujours utiliser des mots clés de conversion tels que CStrCType Operator, qui dirigent le .NET Framework pour tenter la conversion.
Note
L’erreur de conversion restrictive est supprimée pour les conversions des éléments d’une For Each…Next collection vers la variable de contrôle de boucle. Pour plus d’informations et d’exemples, consultez la section « Conversions étroites » dans For Each... Instruction suivante.
Protection de conversion restrictive
L’inconvénient de la réduction des conversions est qu’elles peuvent échouer au moment de l’exécution. Par exemple, si une String variable contient autre chose que « True » ou « False », elle ne peut pas être convertie en Boolean. S’il contient des caractères de ponctuation, la conversion en type numérique échoue. Sauf si vous savez que votre String variable contient toujours des valeurs que le type de destination peut accepter, vous ne devez pas essayer de conversion.
Si vous devez effectuer une conversion vers String un autre type de données, la procédure la plus sûre consiste à placer la tentative de conversion dans try ... Catch... Enfin, instruction. Cela vous permet de gérer un échec d’exécution.
Tableaux de caractères
Un tableau unique Char et un tableau d’éléments s’élargissent Char tous deux à String. Toutefois, String ne s’élargit pas à Char(). Pour convertir une String valeur en tableau Char , vous pouvez utiliser la ToCharArray méthode de la System.String classe.
Valeurs sans signification
En général, String les valeurs ne sont pas significatives dans d’autres types de données, et la conversion est très artificielle et dangereuse. Dans la mesure du possible, vous devez limiter l’utilisation des String variables aux séquences de caractères pour lesquelles elles sont conçues. Vous ne devez jamais écrire de code qui s’appuie sur des valeurs équivalentes dans d’autres types.