在今天的工作中,我们将这一尝试汇总在一起:
xquery version "1.0";
declare option saxon:output "omit-xml-declaration=yes";
declare variable $x := 99;
string-join(
for $b in (128,64,32,16,8,4,2,1)
let $xm := $x mod ($b*2)
return
if ( $xm >= $b ) then "1" else "0"
, "")
你有更好的方法吗?
考虑到奥利弗的答案,我已经做出了相反的功能。
declare function local:bin-byte($x as xs:string) as xs:unsignedByte
{
let $binary-nibbles := ("0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111")
return xs:unsignedByte(
(index-of( $binary-nibbles, substring($x,1,4) )-1) * 16
+ (index-of( $binary-nibbles, substring($x,5,4) )-1)
)
};
答案 0 :(得分:2)
作为次要注意事项,如果您要返回文字而不是XML,那么最好设置method=text
而不是omit-xml-declaration=yes
,尽管在这种情况下它没有任何区别。
另一种解决方案是使用查找表:
declare function local:binary($x as xs:unsignedByte) as xs:string
{
let $binary-nibbles := ("0000", "0001", "0010", "0011",
"0100", "0101", "0110", "0111",
"1000", "1001", "1010", "1011",
"1100", "1101", "1110", "1111")
return concat($binary-nibbles[$x idiv 16 + 1],
$binary-nibbles[$x mod 16 + 1])
};
答案 1 :(得分:1)
如果速度较慢,则递归函数清晰:
declare function local:decimal-to-binary ($d as xs:integer) as xs:string {
if ($d > 0)
then concat(local:decimal-to-binary(floor($d div 2)),$d mod 2)
else ""
};
例如
local:decimal-to-binary(42)
with inverse:
declare function local:binary-to-decimal($b as xs:string) as xs:integer {
if ($b ne "")
then local:binary-to-decimal(substring($b, 1, string-length($b)- 1)) * 2
+ number(substring ($b, string-length($b),1))
else 0
};
本地:二进制到十进制(本地:十进制到二进制(42))
答案 2 :(得分:1)
我能想到的最有效的反向方式(至少在XQSharp中)是:
declare function local:binary-string-to-integer($binary as xs:string)
as xs:integer
{
local:binary-codepoints-to-integer(string-to-codepoints($binary), 1, 0)
};
declare function local:binary-codepoints-to-integer(
$codepoints as xs:integer*,
$current-index as xs:integer,
$result as xs:integer)
as xs:integer
{
let $current-codepoint := $codepoints[$current-index]
return
if (empty($current-codepoint))
then $result
else local:binary-codepoints-to-integer(
$codepoints,
$current-index + 1,
2 * $result + $current-codepoint - string-to-codepoints("0"))
};
快速性能测试显示了在解释查询时执行大致相同的两种方法,但在编译查询时此方法的速度提高了约50%。递归函数方法的优点还在于不限于无符号字节。
无论哪种方式,运行时间大约为10微秒,因此无需担心。