FLOATS

Thursday, 4 February 2021 · 3 messages · last reply 6 Feb 2021
AL
Adam Law4 Feb 2021 14:58 #
(:
Hello I have a hopefully not too silly question ...
Is there an easy way to remove the exponent notation and return
30000201_30000000
without working out where the E is in the parts and padding zeros
  ====> <a>
    <d>3.0000201E7_3.0E7</d>
  </a>
:)
declare function local:sumVec($a,$opt){
  let $a := <x>{for $w at $pos in $a
               return
                  for $v at $pos in  tokenize(xs:string($w),"_")
                    return element {'a'} { (attribute {'pos'} {$pos}, try
{xs:float($v)} catch * {0} )}
                  }</x>
  let $b :=  string-join(for $w in distinct-values($a//@pos)
               return if ($opt=0) then sum($a/a[@pos=$w]) ,"_")
 return $b
};

let $a := ''
return  <a>

<d>{local:sumVec(('10000001_10000000','10000000_10000000','10000000_10000000','100_',100),0)}</d>
</a>
AL
Adam Law4 Feb 2021 17:46 #
Many thanks Christian - I don't know why I didn't think of decimal. I will review my xquery types and arrays. Thanks again - much appreciated :) Adam ! lobotomy()
Quoted text · Christian Grün · 72 lines
On Thu, Feb 4, 2021 at 11:57 PM Christian Grün <christian.gruen at gmail.com> wrote: > Hi Adam, > > It’s recommendable to use xs:decimal instead of xs:float. Here’s one > solution… > > declare function local:sumVec($seq) { > let $count := max(($seq ! string() ! > replace(., '[^_]', '') ! string-length())) + 1 > let $sums := ( > for $c in 1 to $count > return sum( > for $item in $seq > let $tokens := tokenize(string($item), '_') > return try { xs:decimal($tokens[$c]) } catch * { 0 } > ) > ) > return string-join($sums, '_') > }; > > …and another one (presumably more cryptic): > > declare function local:sumVec($seq) { > let $numbers := ( > for $item in $seq > return array { > for $token in tokenize(string($item), '_') > return try { xs:decimal($token) } catch * { 0 } > } > ) > return string-join( > for $c in 1 to max($numbers ! array:size(.)) > return sum($numbers[array:size(.) >= $c]?($c)) > , '_') > }; > > Hope this helps, > Christian > > > > On 2/4/21, Adam Law <adamjameslaw at gmail.com> wrote: > > (: > > Hello I have a hopefully not too silly question ... > > Is there an easy way to remove the exponent notation and return > > 30000201_30000000 > > without working out where the E is in the parts and padding zeros > > ====> <a> > > <d>3.0000201E7_3.0E7</d> > > </a> > > :) > > declare function local:sumVec($a,$opt){ > > let $a := <x>{for $w at $pos in $a > > return > > for $v at $pos in tokenize(xs:string($w),"_") > > return element {'a'} { (attribute {'pos'} {$pos}, try > > {xs:float($v)} catch * {0} )} > > }</x> > > let $b := string-join(for $w in distinct-values($a//@pos) > > return if ($opt=0) then sum($a/a[@pos=$w]) ,"_") > > return $b > > }; > > > > let $a := '' > > return <a> > > > > > <d>{local:sumVec(('10000001_10000000','10000000_10000000','10000000_10000000','100_',100),0)}</d> > > </a> > > >
CG
Christian Grün6 Feb 2021 23:10 #
Hi Adam, It’s recommendable to use xs:decimal instead of xs:float. Here’s one solution…
declare function local:sumVec($seq) {
  let $count := max(($seq ! string() !
    replace(., '[^_]', '') ! string-length())) + 1
  let $sums := (
    for $c in 1 to $count
    return sum(
      for $item in $seq
      let $tokens := tokenize(string($item), '_')
      return try { xs:decimal($tokens[$c]) } catch * { 0 }
    )
  )
  return string-join($sums, '_')
};
…and another one (presumably more cryptic):
declare function local:sumVec($seq) {
  let $numbers := (
    for $item in $seq
    return array {
      for $token in tokenize(string($item), '_')
      return try { xs:decimal($token) } catch * { 0 }
    }
  )
  return string-join(
    for $c in 1 to max($numbers ! array:size(.))
    return sum($numbers[array:size(.) >= $c]?($c))
  , '_')
};
Hope this helps, Christian

⚡Generated with XQuery