Risoluzione dei problemi relativi ai tipi di dati (Visual Basic)Troubleshooting Data Types (Visual Basic)

In questa pagina sono elencati alcuni problemi comuni che possono verificarsi quando si eseguono operazioni sui tipi di dati intrinseci.This page lists some common problems that can occur when you perform operations on intrinsic data types.

Le espressioni a virgola mobile non vengono confrontate come ugualiFloating-Point Expressions Do Not Compare as Equal

Quando si utilizzano numeri a virgola mobile (tipo didati singolo e tipo di dati Double), tenere presente che vengono archiviati come frazioni binarie.When you work with floating-point numbers (Single Data Type and Double Data Type), remember that they are stored as binary fractions. Ciò significa che non è possibile mantenere una rappresentazione esatta di qualsiasi quantità che non sia una frazione binaria (nel formato k/(2 ^ n), dove k e n sono numeri interi.This means they cannot hold an exact representation of any quantity that is not a binary fraction (of the form k / (2 ^ n) where k and n are integers). 0,5 (= 1/2) e 0,3125 (= 5/16), ad esempio, possono essere mantenuti come valori precisi, mentre 0,2 (= 1/5) e 0,3 (= 3/10) possono essere solo approssimazioni.For example, 0.5 (= 1/2) and 0.3125 (= 5/16) can be held as precise values, whereas 0.2 (= 1/5) and 0.3 (= 3/10) can be only approximations.

A causa di questa imprecisione, non è possibile basarsi sui risultati esatti quando si opera sui valori a virgola mobile.Because of this imprecision, you cannot rely on exact results when you operate on floating-point values. In particolare, due valori teoricamente uguali potrebbero presentare rappresentazioni leggermente diverse.In particular, two values that are theoretically equal might have slightly different representations.

Per confrontare le quantità a virgola mobileTo compare floating-point quantities
1. calcolare il valore assoluto della differenza usando il Abs metodo della Math classe nello System spazio dei nomi.1. Calculate the absolute value of their difference by using the Abs method of the Math class in the System namespace.
2. determinare una differenza massima accettabile, in modo che sia possibile considerare le due quantità come uguali per scopi pratici se la differenza non è maggiore.2. Determine an acceptable maximum difference, such that you can consider the two quantities to be equal for practical purposes if their difference is no larger.
3. confrontare il valore assoluto della differenza con la differenza accettabile.3. Compare the absolute value of the difference to the acceptable difference.

Nell'esempio seguente viene illustrato il confronto errato e corretto di due Double valori.The following example demonstrates both incorrect and correct comparison of two Double values.

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))

Nell'esempio precedente viene utilizzato il ToString metodo della Double struttura in modo che sia possibile specificare una precisione maggiore rispetto a quella CStr utilizzata dalla parola chiave.The previous example uses the ToString method of the Double structure so that it can specify better precision than the CStr keyword uses. Il valore predefinito è 15 cifre, ma il formato "G17" lo estende a 17 cifre.The default is 15 digits, but the "G17" format extends it to 17 digits.

L'operatore mod non restituisce risultati accuratiMod Operator Does Not Return Accurate Result

A causa dell'imprecisione dell'archiviazione a virgola mobile, l' operatore mod può restituire un risultato imprevisto quando almeno uno degli operandi è a virgola mobile.Because of the imprecision of floating-point storage, the Mod Operator can return an unexpected result when at least one of the operands is floating-point.

Il tipo di dati Decimal non utilizza la rappresentazione a virgola mobile.The Decimal Data Type does not use floating-point representation. Molti numeri non esatti in Single e Double sono esatti in Decimal (ad esempio, 0,2 e 0,3).Many numbers that are inexact in Single and Double are exact in Decimal (for example 0.2 and 0.3). Sebbene l'aritmetica risulti più lenta in Decimal rispetto a virgola mobile, potrebbe valere la riduzione delle prestazioni per ottenere una maggiore precisione.Although arithmetic is slower in Decimal than in floating-point, it might be worth the performance decrease to achieve better precision.

Per trovare il resto integer delle quantità a virgola mobileTo find the integer remainder of floating-point quantities
1. dichiarare le variabili come Decimal .1. Declare variables as Decimal.
2. utilizzare il carattere di tipo letterale D per forzare i valori letterali in Decimal , nel caso in cui i valori siano troppo grandi per il Long tipo di dati.2. Use the literal type character D to force literals to Decimal, in case their values are too large for the Long data type.

Nell'esempio seguente viene illustrata la potenziale imprecisione degli operandi a virgola mobile.The following example demonstrates the potential imprecision of floating-point operands.

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))

Nell'esempio precedente viene utilizzato il ToString metodo della Double struttura in modo che sia possibile specificare una precisione maggiore rispetto a quella CStr utilizzata dalla parola chiave.The previous example uses the ToString method of the Double structure so that it can specify better precision than the CStr keyword uses. Il valore predefinito è 15 cifre, ma il formato "G17" lo estende a 17 cifre.The default is 15 digits, but the "G17" format extends it to 17 digits.

Poiché zeroPointTwo è Double , il relativo valore per 0,2 è una frazione binaria ripetuta in modo infinito con un valore archiviato di 0.20000000000000001.Because zeroPointTwo is Double, its value for 0.2 is an infinitely repeating binary fraction with a stored value of 0.20000000000000001. La divisione di 2,0 per questa quantità restituisce 9.9999999999999995 con un resto di 0.19999999999999991.Dividing 2.0 by this quantity yields 9.9999999999999995 with a remainder of 0.19999999999999991.

Nell'espressione per decimalRemainder , il carattere di tipo letterale D impone entrambi gli operandi a Decimal e 0,2 presenta una rappresentazione precisa.In the expression for decimalRemainder, the literal type character D forces both operands to Decimal, and 0.2 has a precise representation. Pertanto Mod , l'operatore restituisce il resto previsto di 0,0.Therefore the Mod operator yields the expected remainder of 0.0.

Si noti che non è sufficiente dichiarare decimalRemainder come Decimal .Note that it is not sufficient to declare decimalRemainder as Decimal. È inoltre necessario forzare i valori letterali a Decimal oppure utilizzarli per Double impostazione predefinita e decimalRemainder ricevere lo stesso valore non accurato di doubleRemainder .You must also force the literals to Decimal, or they use Double by default and decimalRemainder receives the same inaccurate value as doubleRemainder.

Il tipo booleano non converte in modo accurato il tipo numericoBoolean Type Does Not Convert to Numeric Type Accurately

I valori dei tipi di dati booleani non vengono archiviati come numeri e i valori archiviati non sono destinati a essere equivalenti ai numeri.Boolean Data Type values are not stored as numbers, and the stored values are not intended to be equivalent to numbers. Per la compatibilità con le versioni precedenti, Visual Basic fornisce parole chiave di conversione (funzione CType,, CBool CInt e così via) per la conversione tra i Boolean tipi numerici e.For compatibility with earlier versions, Visual Basic provides conversion keywords (CType Function, CBool, CInt, and so on) to convert between Boolean and numeric types. Tuttavia, altri linguaggi a volte eseguono queste conversioni in modo diverso, come i metodi .NET Framework.However, other languages sometimes perform these conversions differently, as do the .NET Framework methods.

Non scrivere mai codice che si basa su valori numerici equivalenti per True e False .You should never write code that relies on equivalent numeric values for True and False. Laddove possibile, è consigliabile limitare l'utilizzo delle Boolean variabili ai valori logici per i quali sono stati progettati.Whenever possible, you should restrict usage of Boolean variables to the logical values for which they are designed. Se è necessario combinare Boolean e valori numerici, assicurarsi di conoscere il metodo di conversione selezionato.If you must mix Boolean and numeric values, make sure that you understand the conversion method that you select.

Conversione in Visual BasicConversion in Visual Basic

Quando si usano le CType CBool parole chiave di conversione o per convertire i tipi di dati numerici in Boolean , 0 diventa False e tutti gli altri valori diventano True .When you use the CType or CBool conversion keywords to convert numeric data types to Boolean, 0 becomes False and all other values become True. Quando si convertono Boolean i valori in tipi numerici usando le parole chiave di conversione, False diventa 0 e True diventa-1.When you convert Boolean values to numeric types by using the conversion keywords, False becomes 0 and True becomes -1.

Conversione nel FrameworkConversion in the Framework

Il ToInt32 metodo della Convert classe nello System spazio dei nomi converte True in + 1.The ToInt32 method of the Convert class in the System namespace converts True to +1.

Se è necessario convertire un Boolean valore in un tipo di dati numerico, prestare attenzione al metodo di conversione utilizzato.If you must convert a Boolean value to a numeric data type, be careful about which conversion method you use.

Il valore letterale carattere genera un errore del compilatoreCharacter Literal Generates Compiler Error

In assenza di caratteri di tipo, Visual Basic presuppone i tipi di dati predefiniti per i valori letterali.In the absence of any type characters, Visual Basic assumes default data types for literals. Il tipo predefinito per un valore letterale carattere, racchiuso tra virgolette ( " " ), è String .The default type for a character literal — enclosed in quotation marks (" ") — is String.

Il String tipo di dati non viene ampliato al tipo di dati char.The String data type does not widen to the Char Data Type. Ciò significa che se si desidera assegnare un valore letterale a una Char variabile, è necessario eseguire una conversione verso un tipo di testo più piccolo o forzare il valore letterale nel Char tipo.This means that if you want to assign a literal to a Char variable, you must either make a narrowing conversion or force the literal to the Char type.

Per creare un valore letterale Char da assegnare a una variabile o a una costanteTo create a Char literal to assign to a variable or constant
1. dichiarare la variabile o la costante come Char .1. Declare the variable or constant as Char.
2. racchiudere il valore del carattere tra virgolette ( " " ).2. Enclose the character value in quotation marks (" ").
3. seguire le virgolette doppie di chiusura con il carattere di tipo letterale C per forzare il valore letterale in Char .3. Follow the closing double quotation mark with the literal type character C to force the literal to Char. Questa operazione è necessaria se l'opzione di controllo del tipo (istruzione Option Strict) è On ed è auspicabile in ogni caso.This is necessary if the type checking switch (Option Strict Statement) is On, and it is desirable in any case.

Nell'esempio seguente vengono illustrate le assegnazioni non riuscite e corrette di un valore letterale a una Char variabile.The following example demonstrates both unsuccessful and successful assignments of a literal to a 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")

Esiste sempre un rischio nell'utilizzo di conversioni verso un tipo di caratteri più piccolo, perché possono avere esito negativo in fase di esecuzione.There is always a risk in using narrowing conversions, because they can fail at run time. Ad esempio, una conversione da String a Char può avere esito negativo se il String valore contiene più di un carattere.For example, a conversion from String to Char can fail if the String value contains more than one character. Pertanto, è preferibile programmare di utilizzare il C carattere tipo.Therefore, it is better programming to use the C type character.

Conversione di stringa non riuscita in fase di esecuzioneString Conversion Fails at Run Time

Il tipo di dati String partecipa a pochissime conversioni verso un tipo di dati più grande.The String Data Type participates in very few widening conversions. Stringviene ampliato solo a se stesso e e Object solo Char e Char() ( Char matrice) si ampliano a String .String widens only to itself and Object, and only Char and Char() (a Char array) widen to String. Questo perché String variabili e costanti possono contenere valori che altri tipi di dati non possono contenere.This is because String variables and constants can contain values that other data types cannot contain.

Quando l'opzione di controllo del tipo (Option Strict Statement) è On , il compilatore non consente tutte le conversioni implicite verso un tipo di caratteri più piccolo.When the type checking switch (Option Strict Statement) is On, the compiler disallows all implicit narrowing conversions. Sono inclusi quelli che coinvolgono String .This includes those involving String. Il codice può comunque usare parole chiave di conversione CStr , ad esempio e la funzione CType, che indirizzano l'.NET Framework per tentare la conversione.Your code can still use conversion keywords such as CStr and CType Function, which direct the .NET Framework to attempt the conversion.

Nota

L'errore di conversione verso un tipo di ristringimento viene eliminato per le conversioni dagli elementi di una For Each…Next raccolta alla variabile di controllo del ciclo.The narrowing-conversion error is suppressed for conversions from the elements in a For Each…Next collection to the loop control variable. Per ulteriori informazioni ed esempi, vedere la sezione relativa alle conversioni verso un tipo di dati più piccolo in per ciascuna... Istruzione successiva.For more information and examples, see the "Narrowing Conversions" section in For Each...Next Statement.

Riduzione della protezione della conversioneNarrowing Conversion Protection

Lo svantaggio delle conversioni verso un tipo di restringimento è che possono avere esito negativo in fase di esecuzione.The disadvantage of narrowing conversions is that they can fail at run time. Ad esempio, se una String variabile contiene un valore diverso da "true" o "false", non può essere convertito in Boolean .For example, if a String variable contains anything other than "True" or "False," it cannot be converted to Boolean. Se contiene caratteri di punteggiatura, la conversione in qualsiasi tipo numerico ha esito negativo.If it contains punctuation characters, conversion to any numeric type fails. Se non si è certi che la String variabile contenga sempre valori che possono essere accettati dal tipo di destinazione, non provare a eseguire una conversione.Unless you know that your String variable always holds values that the destination type can accept, you should not try a conversion.

Se è necessario eseguire la conversione da String a un altro tipo di dati, la procedura più sicura consiste nel racchiudere la tentata conversione nell'oggetto try... Rileva... Istruzione finally.If you must convert from String to another data type, the safest procedure is to enclose the attempted conversion in the Try...Catch...Finally Statement. In questo modo è possibile gestire un errore in fase di esecuzione.This lets you deal with a run-time failure.

Matrici di caratteriCharacter Arrays

Una singola Char e una matrice di Char elementi si ampliano a String .A single Char and an array of Char elements both widen to String. Tuttavia, non String si amplia a Char() .However, String does not widen to Char(). Per convertire un String valore in una Char matrice, è possibile usare il ToCharArray metodo della System.String classe.To convert a String value to a Char array, you can use the ToCharArray method of the System.String class.

Valori non significativiMeaningless Values

In generale, String i valori non sono significativi in altri tipi di dati e la conversione è altamente artificiale e pericolosa.In general, String values are not meaningful in other data types, and conversion is highly artificial and dangerous. Laddove possibile, è consigliabile limitare l'utilizzo delle String variabili alle sequenze di caratteri per le quali sono progettate.Whenever possible, you should restrict usage of String variables to the character sequences for which they are designed. Non scrivere mai codice che si basa su valori equivalenti di altri tipi.You should never write code that relies on equivalent values in other types.

Vedere ancheSee also