以二进制输出四元虚数基数


17

编写一个函数或程序,输出显示为二进制数字的Quater-虚数基数。基数为2 i,其中i是-1的平方根。有关i的更多详细信息,请参见复数。每个数字位置可以从0到3(四进制),因为每个实数和虚数部分的大小是前一个实数和虚数部分的-4倍。是二进制的季位数如下:,,及。0: 001: 012: 103: 11

数字位置细分:

re   im       16 -8i  -4  2i   1 -0.5i, etc.
 4    0        1   0   3   0   0        (quaternary representation)
              01  00  11  00  00        (binary representation)

数字100110000是1x16 + 3x-4 = 16 + -12 = 4。

re   im       16 -8i  -4  2i   1 -0.5i, etc.
 0    5        0   0   0   3   0   2    (quaternary representation)
              00  00  00  11  00 .10    (binary representation)

该数字1100.1是3x2 i + 2x-0.5 i = 6 i + -i = 5 i

您的代码将使用一对数字,可以是整数或浮点数,并将复数输出为一串二进制数字。第一个数字为实数,第二个输入数字为虚数。仅当存在低于1的非零数字位置(即-0.5 i,-0.25、0.125 i等的任何位置具有非零数字)时,才必须打印二进制点。不允许前导零和尾随零,除非在二进制点之前紧接一个零数字(如果没有其他数字)。输出不得以二进制点开头(* 00.1-错误,0.1-正确,* .1-错误,* 0.10-错误)。您可以假设所有输入数字都将具有有限的二进制表示形式。

测试编号:

re   im            output
 0    0                 0
 1    0                 1
 2    0                10
 3    0                11
 4    0         100110000
-1    0             10011
-2    0             10010
-3    0             10001
 0    1               100.1
 0    2               100
 0    3              1000.1
 0    4              1000
 0   -1                 0.1
 0   -2           1001100
 0   -3           1001100.1
 3    4              1011
 4    3         100111000.1
 6   -9         101110010.1
-6    9       10011100110.1
-9   -6           1110111
 0.5 14.125   10011001101.001001

注意:.1如果虚部为奇数,则所有整数值的输出将以in结尾。

标准代码高尔夫球。


4
这是一个很好的挑战,但解释可能更加清晰。您应该弄清楚该过程:它从复数到交错的四元表示形式,再到二进制表示形式映射0 → 00, 1 → 01, 2 → 10, 3 → 11
林恩

@Mauris我进行了大量修改以解决您的评论。让我知道是否可以进一步改善。
CJ Dennis

2
如果二进制重复出现该怎么办?
Leaky Nun

1
@LeakyNun在挑战中说正确:“您可以假设所有输入数字都将具有有限的二进制表示形式。”
Mego

Answers:


2

JavaScript(ES6),340字节

f=x=>[0,...x.toString(16)].reverse().map(d=>s=d<'.'?s:d<`0`?d+s.slice(0,-1):`${(c=+`0x${d}`+(c>>4)+m^m)>>2&3}${c&3}`+s,c=s='.',m=x<0?3:12)&&s
g=(s,t,n=s.indexOf`.`,m=t.indexOf`.`)=>n<m?g(0+s,t):n>m?g(s,0+t):t[s.length]?g(s+0,t):s.replace(/\d/g,(c,i)=>`${t[i]>>1}${t[i]&1}${c>>1}${c&1}`).replace(/^0+(\d)|\.?0*$/g,'$1')
(r,i)=>g(f(r),f(i/2))

f将数字转换为基数-4.如果数字是整数,则尾随数字)。g取两个基数-4,在两端将其填充相同的长度,.填充位置,将数字混在一起,将所有内容从基数转换4为基数2,最后去除前导零和尾随零。

说明:要在修改后的基数中表示给定的复数,2i我们需要2i在基数2i²(即-4)中表示复数部分的实数部分和一半(即,将虚数部分除以),将数字混在一起,然后从基数转换它们4根据2。为了表示基数中的实数,-4我们从基数4转换开始。备用数字具有正确的符号(在正数的情况下,这些是偶数位置的数字;在负数的情况下,这些是奇数位置的数字),但是其余的数字具有错误的符号和需要进行更正。例子:

 0 -> 000 -> 000 (no correction needed)
 4 -> 010 -> 130 }
 8 -> 020 -> 120 } (correction includes carry)
12 -> 030 -> 110 }

如您所见,更正为 8减去原始数字mod 8。但是,稍微有点方便的计算是原始数字加上3或3(实际上是32位整数算术运算,我们可以简单地编写+0xCCCCCCCC^0xCCCCCCCC为一次转换整个数字)。最后,由于更正适用于替代数字,因此更容易进行初始转换为基数16,该转换将自动选择成对的基数4,然后使用30xC适当的因子进行校正。只是忽略-标志而已。


0

Perl-313字节

由于尚无人发布答案,所以我认为自己会自己开始。

$r=$ARGV[0];$i=$ARGV[1]/2;$m=1;while($r!=int($r)||$i!=int($i)){$c++;$m*=-1;$i*=4;$r*=4}while($r||$i){$r-=($d[$n++]=$r/$m%4)*$m;$i-=($d[$n++]=$i/$m%4)*$m;$m*=-4}$_=join("",map({sprintf"%02b",$_}reverse splice(@d,$c*2)))||"0";@d and$_.=".".join("",map({sprintf"%02b",$_}reverse@d));s/^0+1/1/;s/(\.\d*1)0+$/$1/;print

我敢肯定还有很多机会进一步打高尔夫球。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.