Please forgive me, I haven't used this site very much! I am working in Visual Studio with Visual Basic. I finished programming my project with Option Strict Off, then when I turned Option Strict on, I was alerted that this code was wrong:
Const TAX_Decimal As Decimal = 0.07
The explanation was that "Option Strict On disallows implicit conversions from 'Double' to 'Decimal'"
But I thought I had declared it as a decimal! It made me change it to:
Const TAX_Decimal As Decimal = CDec(0.07)
The only thing I did with this constant was multiply it by a decimal and saved it to a variable declared as a decimal!
Can someone tell me why this is happening?
When the compiler sees a numeric literal, it selects a type based upon the size of the number, punctuation marks, and suffix (if any), and then translates the the sequence of characters in it to that type; all of this is done without regard for what the compiler is going to do with the number. Once this is done, the compiler will only allow the number to be used as its own type, explicitly cast to another type, or in the two cases defined below implicitly converted to another type.
If the number is interpreted as any integer type (
int
,long
, etc.) the compiler will allow it to be used to initialize any integer type in which the number is representable, as well as any binary or decimal floating-point type, without regard for whether or not the number can be represented precisely in that type.If the number is type
Single
[denoted by anf
suffix], the compiler will allow it to be used to initialize aDouble
, without regard for whether the resultingDouble
will accurately represent the literal with which theSingle
was initialized.Numeric literals of type
Double
[including a decimal point, but with no suffix] orDecimal
[a "D" suffix not followed immediately by a plus or minus] cannot be used to initialize a variable of any other, even if the number would be representable precisely in the target type, or the result would be the target type's best representation of the numeric literal in question.Note that conversions between type
Decimal
and the other floating-point types (double
andfloat
) should be avoided whenever possible, since the conversion methods are not very accurate. While there are manydouble
values for which no exactDecimal
representation exists, there is a wide numeric range in whichDecimal
values are more tightly packed thandouble
values. One might expect that converting adouble
would choose the closestDecimal
value, or at least one of theDecimal
values which is between that number and the next higher or lowerdouble
value, but the normal conversion methods do not always do so. In some cases the result may be off by a significant margin.If you ever find yourself having to convert
Double
toDecimal
, you're probably doing something wrong. While there are some operations which are available onDouble
that are not available onDecimal
, the act of converting between the two types means whateverDecimal
result you end up with is apt to be less precise than if all computations had been done in Double`.