Search code examples
ssasmdxolap

Mdx Sum returns non integer value


When have a issue at work where the value returned by the SUM() function isn't treated like a "normal" number when using the value returned together with the Round() function.

Try this MDX for example

WITH 
MEMBER SomeNumber AS 0.595 
SET SomeNumberSet AS 
           {[SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber], [SomeNumber] }

MEMBER SomeNumberSum AS
Round(SUM([SomeNumberSet], [Measures].[SomeNumber]) / 8, 2)


SELECT [SomeNumberSum] ON 0

FROM [SomeCube]

This code returns 0.59, the sum of sets are 4,76, which are then divided by 8 = 0,595. Since MDX is using Bankers rounding this SHOULD be rounded to 0.60.

Just using Round(0,595) gives us the correct result.

Whats even more strange is that if we in the set only uses the SomeNumber 6 times or less and in the Round Function divide with the same multiplier we get 0.6 (which is correct)

Also, if I wrap the Sum() with the StrToValue() function, it works, even if I use more than 5 SomeNumbers in the set

Whats going on?!


Solution

  • Not sure is the actual answer you're looking for. The issue you've has to do with numerical precision, aka rounding errors, more than with MDX.

    If you're in Java, run the following test :

    public void testNumeric()
    {
        double sum = 0.0;
        double value = 0.595;
    
        for (int i = 0; i < 8; i++)
        {
            sum += value;
        }
    
        double prod = value * 8;
        assertEquals(sum / 8, prod / 8);
    }
    

    The assert will fail, strange no ?

    Result : expected:<0.5949999999999999> but was:<0.595>
    

    The first one, sum, is how mdx is calculating the value. You got a slight difference, but it is enough for changing the result of the ROUND().

    Is there a solution ?

    Strictly speaking no, it's an error due to the very nature of the numeric calculation with computers. Practically you can cheat a bit round first to 10 - ROUND(ROUND(MyNumber,10),2), not brillant (10 is an example).

    If you're interested start in wikipedia from here