I have the following code which calculates the percentage of a value (amount stored in a DictAmount) and saves it to DictPercentage except I ended up with negative percentages!
dictPercent.Value( position ) = Ceil( 100 * dictAmount.Value( position ) / DictSumAtPosition.Value( position ) )
// if it is 0 then stay zero, if it is more but less than 1 then round up to 1
To find out what was going on I added some variables:
[code]dim a as double = dictAmount.Value( position )
dim b as Double = DictSumAtPosition.Value( position )
dictPercent.Value( position ) = Ceil( 100 * dictAmount.Value( position ) / DictSumAtPosition.Value( position ) )
if dictPercent.Value( position ) < 0 then
break
end if[/code]
Sure enough the debugger breaks and the values are
a = 23164713,
b = 532854157,
dictPercent.Value( position ) = -3.0
It should be 4.3, not -3.0.
Now the weird thing (for me): If I comment out the line
dictPercent.Value( position ) = Ceil( 100 * dictAmount.Value( position ) / DictSumAtPosition.Value( position ) )
and write instead
dictPercent.Value( position ) = Ceil( 100 * a / b)
then it works perfectly.
If I reverse it again I get negative values again.
Dictionary.Value(key) returns a Variant. So you should use IntegerValue, SingleValue, or DoubleValue to make sure you get the right value back from the Variant.
This:
100 * dictAmount.Value( position )
… should be:
... 100 * dictAmount.Value( position ).DoubleValue ...
… and so on for all other.
I never ever use a value returned from a dictionary directly without:
assigning it to another non-Variant variable,
casting it, or
using one of the properties of Variant like DoubleValue or IntegerValue.
When you read from variant, better stuff it in local variable.
This way you can check the value in debugger and you are precise about whether to query double or integer from variant.
The only thing the compiler can use to determine what kind of math to use is “100”, an integer. So it’s going to do the whole thing in integer arithmetic. Evaluating left to right, you start with
100 * 23164713
which overflows to -1978495996.
You could try writing it as
100.0 * …
But it’s much better to be explicit when dealing with variants.