Virgola mobile XOR


15

Il tuo compito è piuttosto semplice. Dati due float, bit a bit xo la loro rappresentazione binaria, e li emette come float.

Per esempio,

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

Restrizioni / chiarimenti:

  • Input / output possono essere forniti con qualsiasi metodo conveniente .
  • Il programma può essere un programma completo o solo una funzione; o va bene.
  • Il tipo float può avere qualsiasi dimensione, ma la dimensione minima è di 2 byte.
  • Sono vietate le scappatoie standard.
  • Il codice più corto vince.

2
L'elenco booleano è considerato un metodo conveniente?
Adám,

23
la "rappresentazione binaria" di un float è estremamente ambigua. Dovrai definire quale rappresentazione stai usando. Ci sono un numero infinito di rappresentazioni, incluso il numero finito già usato dalla vita su questo pianeta, alcuni sono più popolari di altri, come IEEE 754
Reversed Engineer

7
Questa domanda sarebbe più interessante come "xo i valori " piuttosto che "xo le rappresentazioni". Quest'ultimo è ovviamente identico a "xo due numeri interi a 32 bit" in qualsiasi lingua che manchi di un sistema di tipi o ammetta la punzonatura dei tipi, e quindi è piuttosto noioso ...
R .. GitHub STOP HELPING ICE

5
Dobbiamo gestire l'infinito, i subnormali o lo 0 negativo, come input o output?
Grimmy,

3
@Mark: No, come scritto, la domanda riguarda solo xor'ing delle loro rappresentazioni, qualunque esse siano. Il risultato dipende dal formato in virgola mobile ma l'algoritmo è sempre una singola istruzione xor sulla rappresentazione, che è piuttosto noiosa.
R .. GitHub smette di aiutare ICE il

Risposte:


53

codice macchina x86-64, 4 byte

0f 57 c1 c3

Nel montaggio:

xorps xmm0, xmm1
ret

Questa è una funzione richiamabile che accetta due float o double come argomenti (in xmm0e xmm1) e restituisce un float o double (inxmm0 ).

Corrisponde alle convenzioni di chiamata di Windows x64 e SysV ABI x86-64 e funziona sia per float che doppi. (Vengono passati / restituiti nei bassi 4 o 8 byte dei registri XMM).


12

C ++ (gcc) , 74 32 byte

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

Provalo online!

Non ho mai giocato a golf in C ++, quindi sono grato a tutti coloro che hanno contribuito a dimezzare le dimensioni del codice! Una macro che prende i puntatori a due float come argomenti e ha modificato il primo per restituire il risultato.

Grazie a @ 12Me1 per il salvataggio di 2 byte e @Arnauld per il salvataggio di 4! Grazie a @Nishioka per averne salvato altri 14, @Neil altri 6 e @AZTECCO e @Nishioka altri 11! Grazie a @PeterCordes per aver salvato 5 byte!


1
Puoi rimuovere le interruzioni di riga per salvare 2 caratteri, e questo funziona anche in C
Me 21

1
È possibile salvare altri 4 byte con z=*(int*)x^*(int*)y;.
Arnauld,

1
Con estensioni gcc, 54 byte:#define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
Nishioka,

2
Dato che stai usando i puntatori, è legale usare uno degli input come output? Se è così, potresti scrivere (*(int*)x^=*(int*)y).
Neil,

1
Prendendo in considerazione il suggerimento di @ Neil, arriverebbe a 48 byte:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka,

9

Codice macchina pollice ARM, 6 4 byte

48 40 70 47

Nel montaggio:

EORS R0, R1; Esclusivo O dei primi due parametri, memorizzare il risultato nel registro di ritorno
BX LR; Diramazione sul valore memorizzato nel registro dei collegamenti (indirizzo di ritorno)

In base alla convenzione di chiamata standard di Arm, i primi due parametri vengono passati nei registri R0 e R1, i risultati vengono restituiti in R0 e LR contiene l'indirizzo di ritorno. Supponendo che tu stia utilizzando l'ABI soft float con float a 32 bit, questo eseguirà l'operazione desiderata in 4 byte.

-2 byte grazie a Cody Grey


2
Sarebbe possibile utilizzare EORS r0, r1invece, al fine di salvare 2 byte? Questa è solo un'istruzione a 2 byte ( 48 40), rispetto al tuo 4 byte EOR. Stai già prendendo di mira il Thumb, quindi questo dovrebbe funzionare bene, per quanto posso vedere. L'unica differenza è che aggiorna i flag di stato, ma in questo caso non ti interessa l'effetto collaterale.
Cody Gray,

2
Dovresti specificare che questo sta usando l'ABI soft-float che passa gli argomenti FP nei registri interi, non VFP / NEON s0e s1.
Peter Cordes,

6

Python 3 + numpy, 75 59 byte

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

Provalo online!

Definisce un lambda che accetta due array float32 numpy come argomenti e restituisce un array float32 numpy.

Grazie a @ShadowRanger per aver salvato 14 byte e Joel altri 2!

Se l'importazione può essere eliminata (poiché la mia lambda stessa chiama metodi su oggetti numpy piuttosto che su qualsiasi funzione numpy di base), potrei salvare altri 13 byte. Non sono sicuro su questo dalle regole standard del codice golf.


È più breve delle risposte di Jelly e Ruby. Bello!
Eric Duminil,

Puoi radere 27 byte (rilasciandolo a 48 byte) rimuovendo completamente l'importazione (supponi solo che il chiamante ti abbia superato in numpy.float32modo da poter usare i loro metodi) e sostituendo entrambi gli int32usi con 'i'e l' float32uso con 'f'; il dtypeparametro può essere una stringa che viene convertita in reale dtypeper te, e convenientemente, 'i'e 'f'sono modi legali per creare quei tipi, che elimina la necessità per la funzione di importare numpycose nel suo spazio dei nomi. Non sono sicuro se Code Golf è legale rimuovere l'importazione ma assumere comunque numpyinput ...
ShadowRanger


Pensavo che le importazioni dovessero essere incluse, ma non ne sono sicuro. Grazie per la punta sui tipi!
Nick Kennedy,

@NickKennedy: Sì, se è necessaria l'importazione, salva solo 8 byte (due ciascuno da int32a 'i', quattro da float32a 'f'), ma è ancora qualcosa. Se l'importazione è strettamente necessaria, puoi semplicemente cambiarla import numpyper affermare che il pacchetto esiste, senza usare from numpy import*per estrarne i nomi. Ciò richiederebbe altri sei byte, fino a un totale di 61 byte.
ShadowRanger,

6

Gelatina + intorpidimento, 89 77 byte

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

Provalo online!

Ha il dubbio onore di essere più lungo del codice Python 3 che riproduce, in gran parte a causa della necessità di convertire in / da oggetti intorpiditi e del fatto che Numpy non è caricato da Jelly, quindi __import__()è necessario utilizzare il built-in.

Un collegamento monadico che prende i due float come elenco come argomento e restituisce un float.

Valuta il seguente codice Python 3:

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

dove xe ysono sostituiti con l'input.


5

APL (Dyalog Unicode) , SBCS da 14 byte

Programma completo. Richiede una matrice a 1 colonna di due numeri in virgola mobile IEEE 754 a 64 bit (binary64) da stdin. Stampa uno di questi numeri su stdout.

645DR≠⌿11DR

Provalo online!

 prompt (i numeri che collassano su non float possono essere forzati in float con la funzione ⊃⊢⎕DR⍨645,⍨⎕DR)

11⎕DR convert a 1 bit binario (1) D ata R ePresentation (2 righe, 64 colonne della matrice)

≠⌿ riduzione XOR verticale

645⎕DR converti in float a 64 bit (5) Rappresentazione D ata R (numero singolo)



3

Ottava , 59 byte

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

Provalo online!

Typecast è il modo MATLAB / Octave di trasmettere senza cambiare i bit sottostanti. Questo è necessario perché bitxorfunziona solo su numeri interi. Non ho idea del perché non abbiano mai implementato numeri in virgola mobile, anche se puoi specificare esplicitamente AssumedTypecome terzo argomento bitxor. Immagino che l'unico uso sia la programmazione ricreativa.


Le cose bit per bit sui pattern di bit FP sono utili nel linguaggio assembly per fare cose con il bit di segno, o raramente per riempire un numero intero nel campo esponente come parte di exp()un'implementazione. Ma suppongo che Octave abbia già funzioni / operatori per la copia e la negazione. E a loro non interessano le micro-ottimizzazioni come l'uso di AND (con una maschera costante) e quindi di XOR per capovolgere condizionalmente il segno di un valore in base al segno di un altro. In un vero progetto di ottimizzazione in asm (in realtà C con intrinseci AVX) ho usato XOR di float, quindi ho guardato il bit del segno per evitare cmp contro zero.
Peter Cordes,




2

C, 23 byte

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

Provalo online!

Questo potrebbe essere un po 'sfuggente; prende i puntatori a floats come puntatori aint s.

Tuttavia, funziona (dopo tutto è C).

Questo sfrutta l'input accettabile prendendo un puntatore alla variabile e modificandola sul posto. Nessun valore (utilizzabile) viene restituito.


2

JavaScript (Node.js) ,  105  101 byte

Versione più breve del nodo suggerita da @Neil
Salvati altri 4 byte grazie a @ShieruAsakoto

Accetta input come (x)(y).

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

Provalo online!


JavaScript (ES6), 115 byte

Accetta input come un array di 2 float.

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

Provalo online!


FYI Nodo di Bufferparate pochi byte: a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE()).
Neil,

@ Grazie Grazie! (salvato altri 2 byte utilizzando una funzione anziché map)
Arnauld

1
newnew Buffer(4)
Far

1

Wolfram Mathematica , 50 byte

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

Anche se sospetto fortemente che questo potrebbe essere più golfato, i due argomenti in più RealDigits funzione sembrano essere necessari per ottenere un risultato corretto.

Provalo online!


1

Lua , 73 byte

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

Provalo online!

Questo codice presuppone numeri interi e float senza segno a 4 byte su cui è configurata tio.run. Esegui come programma completo con input come argomenti.


1

Rubino , 78 67 byte

-11 byte grazie a @grawity.

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

Provalo online!

L'input è un array di due float.


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

@grawity: fantastico, grazie mille! Il codice è comunque più lungo che in Python, comunque. : - /
Eric Duminil,

1

Java (JDK) , 109 76 byte

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

Provalo online!

È passato un po 'di tempo da quando ho giocato a golf a Java e non sono sicuro di aver bisogno della dichiarazione sull'LHS come parte del conteggio dei byte? Se utilizzasse DoubleBinaryOperator, l'LHS sarebbe più breve, ma l'RHS dovrebbe usare Double.doubleToLongBits e Double.longBitsToDouble, quindi in realtà è più lungo.

Grazie a Neil per un sostanziale risparmio sul conteggio dei byte!


1
IIRC non hai nemmeno bisogno dell'assegnazione come parte del conteggio dei byte, solo come parte di qualsiasi suite di test che potresti includere nel tuo Provalo online! intestazione.
Neil,

@Neil Grazie! Questo fa una grande differenza!
David Conrad,

0

Pulito , 36 byte

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

Provalo online!

Per fortuna i tipi Reale Inthanno le stesse dimensioni su piattaforme a 64 bit ...
Sfortunatamente richiede una firma completa, altrimenti il ​​grafico si trasforma in un pretzel e tutto segfault.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.