Rounding Issue

Monday, 4 July 2016 · 3 messages
PG
prasad gavhane4 Jul 2016 09:39 #

Hi,

I am using BaseX 8.4.3. I found some discriminating results while executing following query in two different ways :

Query :   round(((( $V1 * $V2 )+( $V3 * $V4 )+( $V5 * $V6 ))div( $V1 + $V3
+ $V5 ))*10000) div 10000

1. Type 1 (standalone values)

let $V1 := 1500000000
let $V2 := 0.0926
let $V3 := 1000000000
let $V4 := 0.082
let $V5 := 500000000
let $V6 := 0.0931
let $V7 :=  0.0892
return round(((( $V1 * $V2 )+( $V3 * $V4 )+( $V5 * $V6 ))div( $V1 + $V3 +
$V5 ))*10000) div 10000

Output : 0.0892

2 : Type 2 (values from input xml attached in this mail - val.xml)

let $V1 := data/V1
let $V2 :=  data/V2
let $V3 :=  data/V3
let $V4 :=  data/V4
let $V5 :=  data/V5
let $V6 :=  data/V6
let $V7 := data/V7

return round(((( $V1 * $V2 )+( $V3 * $V4 )+( $V5 * $V6 ))div( $V1 + $V3 +
$V5 ))*10000) div 10000

Output : 0.0891

Is this a bug or am I doing something wrong?

Thanks, Prasad Gavhane.

CG
Christian Grün4 Jul 2016 09:46 #

Hi Prasad,

The difference is here:

Quoted text · prasad gavhane · 1 line
> let $V2 := 0.0926

This value is of type xs:decimal.

  <V2>0.0926</V2>

This value is untyped, and implicitly converted to a double (not a decimal) value when being included in an arithmetic expression. As the following example shows…

4 - 3.1, 4 - 3.1e0

…It’s often a difference if you work with decimals or doubles.

In your case, it may be best to explicitly convert your values before doing the computations:

  let $V1 := xs:decimal(data/V1)
  let $V2 := xs:decimal(data/V2)
  let $V3 := xs:decimal(data/V3)
  let $V4 := xs:decimal(data/V4)
  let $V5 := xs:decimal(data/V5)
  let $V6 := xs:decimal(data/V6)
  let $V7 := xs:decimal(data/V7)
  return round(((( $V1 * $V2 )+( $V3 * $V4 )+( $V5 * $V6 ))div( $V1 +
$V3 + $V5 ))*10000)

Hope this helps, Christian

PG
prasad gavhane4 Jul 2016 11:34 #

Hi,

Thanks for the response.

While digging, I found following results,

1. result for (((( $V1 * $V2 )+( $V3 * $V4 )+( $V5 * $V6 ))div( $V1 + $V3 +
$V5 ))) is "0.08915"

2.result for (((( $V1 * $V2 )+( $V3 * $V4 )+( $V5 * $V6 ))div( $V1 + $V3 +
$V5 ))*10000) is "891.4999999999999"

Hence while multiplying 1 with 10000 ideally it should give 891.5.

Thanks, ​​ Prasad Gavhane.

Quoted text · Christian Grün · 36 lines
On Mon, Jul 4, 2016 at 1:16 PM, Christian Grün <christian.gruen at gmail.com> wrote: > Hi Prasad, > > The difference is here: > > > let $V2 := 0.0926 > > This value is of type xs:decimal. > > <V2>0.0926</V2> > > This value is untyped, and implicitly converted to a double (not a > decimal) value when being included in an arithmetic expression. As the > following example shows… > > 4 - 3.1, 4 - 3.1e0 > > …It’s often a difference if you work with decimals or doubles. > > In your case, it may be best to explicitly convert your values before > doing the computations: > > let $V1 := xs:decimal(data/V1) > let $V2 := xs:decimal(data/V2) > let $V3 := xs:decimal(data/V3) > let $V4 := xs:decimal(data/V4) > let $V5 := xs:decimal(data/V5) > let $V6 := xs:decimal(data/V6) > let $V7 := xs:decimal(data/V7) > return round(((( $V1 * $V2 )+( $V3 * $V4 )+( $V5 * $V6 ))div( $V1 + > $V3 + $V5 ))*10000) > > Hope this helps, > Christian >

⚡Generated with XQuery