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
Written for BaseX 9.4. BaseX may have changed since: please check the current documentation.
⚡Generated with XQuery