Ponto flutuante XOR


15

Sua tarefa é bem simples. Dado dois flutuadores, bit a bit xou a representação binária deles, e a produz como flutuante.

Por exemplo,

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

Restrições / esclarecimentos:

  • A entrada / saída pode ser fornecida por qualquer método conveniente .
  • O programa pode ser um programa completo ou apenas uma função; qualquer um serve.
  • O tipo de flutuação pode ter qualquer tamanho, mas o tamanho mínimo é 2 bytes.
  • As brechas padrão são proibidas.
  • O menor código vence.

2
A lista booleana conta como um método conveniente?
Adám 15/09/19

23
A "representação binária" de um flutuador é extremamente ambígua. Você precisará definir qual representação está usando. Há um número infinito de representações, incluindo o número finito já usado pela vida neste planeta, sendo alguns mais populares que outros, como o IEEE 754
Engenheiro Reverso

7
Essa pergunta seria mais interessante como "xou os valores " em vez de "xou as representações". É claro que este último é idêntico a "xor dois números inteiros de 32 bits" em qualquer idioma que não possua um sistema de tipos ou que admita punção de tipo e, portanto, seja muito chato ...
R .. GitHub PARE DE AJUDAR O GELO

5
Temos que lidar com infinito, subnormal ou 0 negativo, como entrada ou saída?
Grimmy

3
@ Mark: Não, como está escrito, a questão é apenas expor suas representações, quaisquer que sejam essas representações. O resultado depende do formato do ponto flutuante, mas o algoritmo é sempre uma única instrução xor na representação, o que é bastante chato.
R .. GitHub Pare de ajudar o gelo

Respostas:


53

código de máquina x86-64, 4 bytes

0f 57 c1 c3

Na montagem:

xorps xmm0, xmm1
ret

Essa é uma função que pode ser chamada que aceita dois valores flutuantes ou duplos como argumentos (em xmm0 e xmm1) e retorna um valor flutuante ou duplo (in xmm0).

Isso corresponde às convenções de chamada do Windows x64 e da x86-64 SysV ABI e funciona para carros alegóricos e duplos. (Eles são passados ​​/ retornados nos baixos 4 ou 8 bytes de registros XMM).


12

C ++ (gcc) , 74 32 bytes

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

Experimente online!

Eu nunca tinha jogado golfe em C ++, por isso sou grato a todos aqueles que ajudaram a reduzir o tamanho do código pela metade! Uma macro que leva ponteiros para dois carros alegóricos como argumentos e modificou o primeiro para retornar o resultado.

Graças a @ 12Me1 por salvar 2 bytes e @Arnauld por salvar 4! Graças a @Nishioka por salvar outros 14, @Neil mais 6 e @AZTECCO e @Nishioka mais 11! Agradecemos a @PeterCordes por salvar 5 bytes!


1
Você pode remover as quebras de linha para salvar 2 caracteres, e isso também funciona em C
12Me21

1
Você pode salvar mais 4 bytes com z=*(int*)x^*(int*)y;.
Arnauld

1
Com extensões gcc, 54 bytes:#define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
Nishioka

2
Como você está usando ponteiros, é legal usar uma das entradas como saída? Se sim, você poderia escrever (*(int*)x^=*(int*)y).
Neil

1
Levando em consideração a sugestão de @ Neil, chegaria a 48 bytes:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka

9

Código de máquina do polegar ARM, 6 4 bytes

48 40 70 47

Na montagem:

EORS R0, R1; Exclusivo Ou dos dois primeiros parâmetros, o resultado da loja no registro de retorno
BX LR; Ramifique para o valor armazenado no Link Register (endereço de retorno)

Sob a convenção de chamada de braço padrão, os dois primeiros parâmetros são passados ​​nos registradores R0 e R1, os resultados são retornados em R0 e LR mantém o endereço de retorno. Supondo que você esteja usando a ABI de flutuação suave com flutuações de 32 bits, isso executará a operação desejada em 4 bytes.

-2 bytes graças a Cody Gray


2
Seria possível usar em EORS r0, r1vez disso, para salvar 2 bytes? Essa é apenas uma instrução de 2 bytes ( 48 40), em comparação com seus 4 bytes EOR. Você já está segmentando o Thumb, então isso deve funcionar bem, até onde posso ver. A única diferença é que ele atualiza os sinalizadores de status, mas você não se importa com esse efeito colateral nesse caso.
Cody cinzento

2
Você deve especificar que isso está usando a ABI de flutuação suave que passa argumentos de FP em registros inteiros, não VFP / NEON s0e s1.
Peter Cordes

6

Python 3 + numpy, 75 59 bytes

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

Experimente online!

Define um lambda que usa duas matrizes float32 numpy como argumentos e retorna uma matriz float32 numpy.

Agradecemos a @ShadowRanger por salvar 14 bytes e a Joel mais 2!

Se a importação puder ser descartada (como meu próprio lambda chama métodos em objetos numpy em vez de quaisquer funções numpy básicas), eu poderia salvar mais 13 bytes. Não tenho certeza disso nas regras padrão do código de golfe.


É mais curto que as respostas de Jelly e Ruby. Agradável!
Eric Duminil

Você pode cortar 27 bytes (reduzindo-o para 48 bytes) removendo completamente a importação (suponha que o chamador tenha passado por você numpy.float32para que você possa usar os métodos deles) e substituindo ambos os int32usos por 'i'e o float32uso por 'f'; o dtypeparâmetro pode ser uma string que é convertida em real dtypepara você e, convenientemente, 'i'e 'f'são formas legais de criar esses tipos, o que elimina a necessidade de a função importar numpycoisas para seu namespace. Não tenho certeza se é Código Golf legal para remover a importação, mas ainda assumir numpyentradas ...
ShadowRanger


Eu pensei que as importações tinham que ser incluídas, mas não tenho certeza. Obrigado pela dica sobre os tipos!
Nick Kennedy

@NickKennedy: Sim, se a importação for necessária, ela salva apenas 8 bytes (dois de cada int32para 'i', quatro de float32para 'f'), mas isso ainda é algo. Se a importação for estritamente necessária, você pode alterá-la import numpypara afirmar que o pacote existe, sem usar from numpy import*para extrair nomes dele. Isso daria mais seis bytes, totalizando 61 bytes.
ShadowRanger

6

Gelatina + numpy, 89 77 bytes

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

Experimente online!

Tem a honra duvidosa de ser maior que o código Python 3 que ele reproduz, em grande parte devido à necessidade de converter de / para um objeto numpy e pelo fato de que o numpy não é carregado pelo Jelly, então o __import__() built-in deve ser usado.

Um link monádico usando os dois flutuadores como uma lista como argumento e retornando um flutuador.

Avalia o seguinte código Python 3:

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

onde xe ysão substituídos pela entrada.


5

APL (Dyalog Unicode) , 14 bytes SBCS de

Programa completo. Solicita a matriz de 1 coluna de dois números de ponto flutuante IEEE 754 de 64 bits (binary64) do stdin. Imprime um desses números em stdout.

645DR≠⌿11DR

Experimente online!

 prompt (números que são recolhidos para não-flutuantes podem ser forçados a flutuar com a função ⊃⊢⎕DR⍨645,⍨⎕DR )

11⎕DR convertido para um-bit binário (1) D ATA R ePresentation (2-fileira, matriz de 64 coluna)

≠⌿ redução vertical de XOR

645⎕DR convertido para 64 bits flutuador (5) D ATA R ePresentation (número único)


4

VAX BASIC (mais tarde VMS BASIC e depois Compaq Basic) , 11 bytes

H = F XOR G

Parece um pouco tolo para mim, obviamente, os idiomas mais antigos se sairão melhor porque não se preocuparam tanto com os problemas de digitação forte.


1
Bem-vindo ao site e boa primeira resposta! Eu editei o que parece ser um cabeçalho estranho, mas se não se sentir livre para editá-lo de volta, juntamente com qualquer informação que acompanha
caird coinheringaahing

3

Oitava , 59 bytes

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

Experimente online!

Typecast é a maneira de transmitir MATLAB / Octave sem alterar os bits subjacentes. Isso é necessário porque bitxorfunciona apenas em números inteiros. Não faço ideia por que eles nunca implementaram números de ponto flutuante, mesmo que você possa especificar explicitamente AssumedTypecomo um terceiro argumento para bitxor. Eu acho que o único uso é a programação recreativa.


Coisas bit a bit em padrões de bits FP são úteis na linguagem assembly para fazer coisas com o bit de sinal ou raramente para inserir um número inteiro no campo expoente como parte de uma exp()implementação. Mas suponho que o Octave já tenha funções / operadores para copysign e negação. E eles não se preocupam com micro-otimizações, como usar AND (com uma máscara constante) e depois o XOR para alternar condicionalmente o sinal de um valor com base no sinal de outro. Em um projeto de otimização real em asm (na verdade, C com intrínsecas AVX), usei o XOR de flutuadores e depois observei o bit de sinal para evitar cmp contra zero.
Peter Cordes




2

C, 23 bytes

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

Experimente online!

Isso pode ser um pouco complicado; leva os ponteiros para floats como ponteiros para ints.

No entanto, funciona (afinal é C).

Isso tira proveito da entrada aceitável, pegando um ponteiro na variável e modificando-a no local. Nenhum valor (utilizável) é retornado.


2

JavaScript (Node.js) ,  105  101 bytes

Versão mais curta do nó sugerida por @Neil
Economizou mais 4 bytes graças a @ShieruAsakoto

Toma entrada como (x)(y).

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

Experimente online!


JavaScript (ES6), 115 bytes

Aceita entrada como uma matriz de 2 carros alegóricos.

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

Experimente online!


FYI Nó de Buffersalva alguns bytes: a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE()).
Neil

@ Neil Thanks! (salvo mais 2 bytes, utilizando uma função em vez de map)
Arnauld

1
Deixando cair a newna new Buffer(4)também deve trabalhar IIRC
Shieru Asakoto

1

Wolfram Mathematica , 50 bytes

BitXor@@(FromDigits[RealDigits[#,2,32,0][[1]],2]&)

Embora eu suspeite fortemente que isso possa ser mais complicado, os dois argumentos extras em RealDigits função parecem ser necessários para obter um resultado correto.

Experimente online!


1

Lua , 73 bytes

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

Experimente online!

Esse código pressupõe números inteiros não assinados de 4 bytes e flutua com a configuração ativada tio.run. Execute como programa completo com entrada como argumentos.


1

Ruby , 78 67 bytes

-11 bytes graças a @grawity.

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

Experimente online!

Entrada é uma matriz de dois carros alegóricos.


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

@ grrawity: Impressionante, muito obrigado! O código ainda é mais longo do que em Python, no entanto. : - /
Eric Duminil

1

Java (JDK) , 109 76 bytes

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

Experimente online!

Já faz um tempo desde que jogava golfe em Java e não tenho certeza se preciso da declaração no LHS como parte da contagem de bytes? Se ele usasse o DoubleBinaryOperator, o LHS seria mais curto, mas o RHS teria que usar o Double.doubleToLongBits e o Double.longBitsToDouble, então é mais longo.

Agradecemos a Neil por uma economia substancial na contagem de bytes!


1
No IIRC, você nem precisa da atribuição como parte da contagem de bytes, apenas como parte de qualquer suíte de testes que possa incluir no seu Experimente-o online! cabeçalho.
Neil

@ Neil Obrigado! Isso faz uma grande diferença!
David Conrad

0

Limpo , 36 bytes

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

Experimente online!

Felizmente, os tipos Reale Intsão do mesmo tamanho em plataformas de 64 bits ...
Infelizmente, exige uma assinatura completa, caso contrário, o gráfico se transforma em um pretzel e tudo mais.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.