浮点异或


15

您的任务非常简单。给定两个浮点数,将它们按位进行异或,然后将其输出为浮点数。

例如,

Normal: 16.7472 ^ 123.61 = 7.13402e-37
Binary: 01000001100001011111101001000100 ^ 01000010111101110011100001010010 = 00000011011100101100001000010110

Normal: 2.2 ^ 4.4 = 1.17549e-38
Binary: 01000000000011001100110011001101 ^ 01000000100011001100110011001101 = 00000000100000000000000000000000

Normal: 7.898 ^ 3.4444 = 1.47705e-38
Binary: 01000000111111001011110001101010 ^ 01000000010111000110101001111111 = 00000000101000001101011000010101

限制/说明:

  • 输入/输出可以通过任何方便的方法给出。
  • 该程序可以是完整程序,也可以只是功能。两者都很好。
  • 浮点类型可以是任意大小,但最小大小为2个字节。
  • 禁止出现标准漏洞。
  • 最短的代码获胜。

2
布尔列表是否算作方便的方法?
亚当

23
浮点数的“二进制表示”非常含糊。您需要定义要使用的表示形式。有无数种表示形式,包括地球上生命已经使用的有限种表示形式,其中一些比其他形式更受欢迎,例如IEEE 754
Reversed Engineer'Sep

7
这个问题将更有趣,因为“对值进行异或”而不是“对表示进行异或”。后者在缺少类型系统或允许类型调整的任何语言中,当然与“异或两个32位整数”相同,因此非常无聊……
R .. GitHub停止帮助ICE

5
我们是否必须将无穷大,次正规或负0作为输入或输出?
Grimmy19

3
@Mark:不,按照书面要求,无论这些表示是什么,问题都只是关于异或它们的表示。结果取决于浮点格式,但是算法始终是表示形式上的单个异或指令,这很无聊。
R .. GitHub停止帮助ICE

Answers:


53

x86-64机器码,4个字节

0f 57 c1 c3

组装中:

xorps xmm0, xmm1
ret

这是一个可调用函数,该函数将两个float或double用作参数(in xmm0xmm1),并返回一个float或double(in xmm0)。

它与Windows x64 x86-64 SysV ABI 的调用约定均匹配,并且适用于浮点数和双精度数。(它们在XMM寄存器的低4或8字节中传递/返回)。


12

C ++(gcc)74 32字节

#define f(x,y)*(int*)x^=*(int*)y

在线尝试!

我以前没有玩过C ++,所以感谢所有帮助将代码大小减少一半的人!一个宏,该宏将指向两个浮点数的指针作为其参数,并修改了第一个以返回结果。

感谢@ 12Me1保存2个字节,而@Arnauld保存4个字节!感谢@Nishioka节省了另外14个,@ Neil再节省了6个,@ AZTECCO和@Nishioka又节省了11个!感谢@PeterCordes节省了5个字节!


1
您可以删除换行符以保存2个字符,这在C语言中也适用
19Me

1
您还可以使用保存4个字节z=*(int*)x^*(int*)y;
Arnauld

1
带有gcc扩展名的54个字节: #define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
Nishioka

2
由于您使用的是指针,因此使用输入之一作为输出是否合法?如果是这样,您可以编写(*(int*)x^=*(int*)y)
尼尔,

1
考虑到@Neil的建议,它将达到48个字节:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka

9

ARM Thumb机器代码,6 4字节

48 40 70 47

组装中:

EORS R0,R1; 前两个参数的异或,将结果存储在返回寄存器中
BX LR; 跳转到链接寄存器中存储的值(返回地址)

根据标准Arm调用约定,前两个参数在寄存器R0和R1中传递,结果在R0中返回,而LR保留返回地址。假设您正在使用具有32位浮点数的软浮点ABI,这将以4个字节执行所需的操作。

-2字节感谢Cody Gray


2
EORS r0, r1为了节省2个字节,可以改为使用吗?48 40与您的4字节相比,这只是2字节的指令()EOR。您已经定位到Thumb,据我所知,这应该可以正常工作。唯一的区别是它会更新状态标志,但是在这种情况下,您不必担心这种副作用。
科迪·格雷

2
您应该指定它使用的是软浮点ABI,它在整数寄存器中传递FP args,而不是VFP / NEON s0s1
彼得·科德斯

6

Python 3 + numpy,75 59字节

lambda x,y:(x.view("i")^y.view("i")).view("f")
import numpy

在线尝试!

定义一个lambda,该lambda将两个numpy float32数组作为其参数,并返回一个numpy float32数组。

感谢@ShadowRanger节省了14个字节,而Joel又节省了2个字节!

如果可以删除导入(因为我的lambda本身调用的是numpy对象而不是任何基本的numpy函数的方法),那么我可以再节省13个字节。我从代码高尔夫球标准规则对此不确定。


它比Jelly和Ruby的答案短。真好!
埃里克·杜米尼尔

您可以通过彻底消除了进口剃掉27个字节(它下降到48个字节)(只是假设调用者传递你numpy.float32这么你可以用自己的方法)和更换都int32与用途'i'float32使用用途'f'; 该dtype参数可以是一个字符串,可以dtype为您方便地转换为实数,'i'并且'f'是制作这些dtypes的合法方法,从而完全不需要该函数将numpy内容导入其命名空间。不确定删除进口商品是否符合Code Golf的法律,但仍假设numpy输入...
ShadowRanger


我以为进口必须包括在内,但我不确定。感谢您的提示re dtypes!
肯尼迪

@NickKennedy:是的,如果需要导入,它只会保存8个字节(每个从int32to到两个字节'i',四个from float32到to 'f'),但是那还是可以的。如果严格要求导入,则可以将其更改import numpy为断言该软件包存在,而无需使用from numpy import*从中提取名称。那将使您再得到六个字节,总共减少到61个字节。
ShadowRanger

6

果冻 + numpy,89 77字节

“(F(“I^F(“IvF).item()”;"F“¢lẒṾ:/²)Ɓɱ¡vẠ⁷5Rʠ¡7ɼṆṪ{ė4¶Gẉn`¡Ð}ṫȥṄo{b»Ḳ¤¹ṣḢ}jʋƒŒV

在线尝试!

拥有比其复制的Python 3代码更长的可疑荣誉,主要是因为需要与numpy对象之间进行转换以及numpy不由Jelly加载的事实,因此 __import__()必须使用内置的。

以两个浮点数作为列表作为参数并返回浮点数的单子链接。

评估以下Python 3代码:

(__import__('numpy').float32(x).view("i")^__import__('numpy').float32(y).view("i")).view(__import__('numpy').float32).item()

其中xy被输入替换。


5

APL(Dyalog Unicode),14 字节SBCS

完整程序。提示输入来自stdin的两个IEEE 754 64位浮点数(binary64)的1列矩阵。打印一个这样的数字到标准输出。

645DR≠⌿11DR

在线尝试!

 提示(可以使用函数将折叠为非浮点的数字强制为浮点⊃⊢⎕DR⍨645,⍨⎕DR

11⎕DR 转换成1位二进制(1)d ATA ř epresentation(2行,64列的矩阵)

≠⌿ 垂直异或减少

645⎕DR 转换为64位浮点(5)d ATA ř epresentation(单数)



3

八度,59字节

@(a,b)(t=@typecast)(bitxor(t(a,u='int32'),t(b,u)),'single')

在线尝试!

Typecast是不改变基础位的MATLAB / Octave转换方式。这是必需的,因为bitxor仅适用于整数。即使您可以将显式指定AssumedType为的第三个参数,也不知道为什么它们从未实现浮点数bitxor。我猜唯一的用途是娱乐性编程。


FP位模式中的按位填充在汇编语言中非常有用,可以用符号位处理,或者很少将整数填充到指数字段中,作为exp()实现的一部分。但是我认为Octave已经具有用于复制和取反的功能/运算符。而且,他们不关心微优化,例如使用AND(带有恒定掩码),然后使用XOR来基于另一个值的符号有条件地翻转一个值的符号。在asm的实际优化项目中(实际上是带有AVX内部函数的C),我使用了浮点数的XOR,然后查看符号位以避免cmp变为零。
彼得·科德斯




2

C,23个字节

f(int*x,int*y){*x^=*y;}

在线尝试!

这可能有些变化。它将指向floats 的指针作为指向ints的指针。

但是,它确实可以工作(毕竟这是C)。

这可以通过接受指向变量的指针并就地对其进行修改来利用可接受的输入。没有返回(可用)值。


2

JavaScript(Node.js) 105101 字节

@Neil建议的较短节点版本感谢@ShieruAsakoto ,又
节省了4个字节

将输入作为(x)(y)

x=>y=>(v=Buffer(4),v.writeInt32LE((g=n=>v.writeFloatLE(n)&&v.readInt32LE())(x)^g(y)),v.readFloatLE())

在线尝试!


JavaScript(ES6),115个字节

将输入作为2个浮点数的数组。

a=>(v=new DataView(new ArrayBuffer(4))).getFloat32(v.setUint32([x,y]=a.map(n=>v.getUint32(v.setFloat32(0,n))),x^y))

在线尝试!


FYI节点Buffer保存了一些字节:a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE())
尼尔

@尼尔谢谢!(通过使用函数代替节省了2个字节map
Arnauld

1
跌落newnew Buffer(4)也应该IIRC工作
Shieru Asakoto


1

Lua,73个字节

a,b=('II'):unpack(('ff'):pack(...))print((('f'):unpack(('I'):pack(a~b))))

在线尝试!

此代码假定使用4个字节的无符号整数,并且采用float格式(在上进行配置)tio.run。以输入作为参数的完整程序运行。


1

红宝石78 67字节

-11个字节归功于@grawity。

->x{[x.pack("gg").unpack("NN").inject(&:^)].pack(?N).unpack(?g)[0]}

在线尝试!

输入是两个浮点数的数组。


x.map{|v|[v].pack(?g).unpack(?N)[0]}x.pack("gg").unpack("NN")
user1686

@grawity:太好了,非常感谢!但是,代码仍然比Python中的更长。:-/
Eric Duminil

1

Java(JDK)109 76字节

(a,b)->Float.intBitsToFloat(Float.floatToIntBits(a)^Float.floatToIntBits(b))

在线尝试!

自从我打Java高尔夫以来已经有一段时间了,我不确定是否需要LHS声明作为字节数的一部分?如果使用DoubleBinaryOperator,则LHS会更短,但是RHS必须使用Double.doubleToLongBits和Double.longBitsToDouble,因此实际上更长。

感谢Neil大大节省了字节数!


1
IIRC您甚至不需要将分配作为字节数的一部分,而仅将其作为可能包含在“在线试用”中的任何测试套件的一部分即可!标头。
尼尔,

@尼尔,谢谢!那有很大的不同!
戴维·康拉德

0

干净,36字节

f::!Real!Real->Real
f _ _=code{xor%}

在线尝试!

幸运的是,Realand Int类型在64位平台上的大小相同...
不幸的是,需要完整的签名,否则图形将变成椒盐脆饼和所有段错误。

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.