Gleitkomma-XOR

15

Ihre Aufgabe ist ziemlich einfach. Bei zwei gegebenen Floats xor bitweise die Binärdarstellung von ihnen und gibt diese als Float aus.

Beispielsweise,

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

Einschränkungen / Erläuterungen:

  • Die Eingabe / Ausgabe kann auf jede bequeme Weise erfolgen .
  • Das Programm kann ein vollständiges Programm oder nur eine Funktion sein. entweder ist in Ordnung.
  • Der Float-Typ kann eine beliebige Größe haben, die Mindestgröße beträgt jedoch 2 Byte.
  • Standardlücken sind verboten.
  • Kürzester Code gewinnt.
virchau13
quelle
2
Zählt die Boolesche Liste als bequeme Methode?
Adám,
23
Die "binäre Darstellung" eines Floats ist äußerst zweideutig. Sie müssen definieren, welche Darstellung Sie verwenden. Es gibt unendlich viele Darstellungen, einschließlich der endlichen Zahl, die bereits vom Leben auf diesem Planeten verwendet wird. Einige sind beliebter als andere, beispielsweise IEEE 754
Reversed Engineer vom
7
Diese Frage wäre interessanter als "für die Werte " als "für die Darstellungen". Letzteres ist natürlich identisch mit "xor two 32-bit integers" in jeder Sprache, in der es an einem Typensystem mangelt oder die das Punning zulässt, und ist daher ziemlich langweilig ...
R .. GitHub STOP HELPING ICE
5
Müssen wir Unendlich, Subnormale oder negative 0 entweder als Eingabe oder Ausgabe behandeln?
Grimmy
3
@Mark: Nein, wie bereits geschrieben, geht es bei der Frage nur darum, ihre Darstellungen zu bestimmen, unabhängig davon, um welche Darstellungen es sich handelt. Das Ergebnis hängt vom Gleitkommaformat ab, aber der Algorithmus ist immer eine einzelne xoder Anweisung in der Darstellung, was ziemlich langweilig ist.
R .. GitHub STOP HELPING ICE

Antworten:

53

x86-64-Maschinencode, 4 Byte

0f 57 c1 c3

In Montage:

xorps xmm0, xmm1
ret

Dies ist eine aufrufbare Funktion, die zwei Floats oder Double als Argumente (in xmm0und xmm1) verwendet und ein Float oder Double (in xmm0) zurückgibt .

Dies entspricht den Aufrufkonventionen von Windows x64 undDies x86-64 SysV ABI und funktioniert sowohl für Floats als auch für Doubles. (Sie werden in den niedrigen 4 oder 8 Bytes der XMM-Register übergeben / zurückgegeben).

Harold
quelle
12

C ++ (gcc) , 74 32 Bytes

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

Probieren Sie es online!

Ich habe noch nie in C ++ Golf gespielt und bin all jenen dankbar, die geholfen haben, die Größe des Codes zu halbieren! Ein Makro, das Zeiger auf zwei Gleitkommazahlen als Argumente verwendet und das erste so modifiziert, dass es das Ergebnis zurückgibt.

Vielen Dank an @ 12Me1 für das Speichern von 2 Bytes und @Arnauld für das Speichern von 4 Bytes! Vielen Dank an @Nishioka für das Speichern von weiteren 14, @Neil für weitere 6 und @AZTECCO und @Nishioka für weitere 11! Vielen Dank an @PeterCordes für die Einsparung von 5 Bytes!

Nick Kennedy
quelle
1
Sie können die Zeilenumbrüche entfernen, um 2 Zeichen zu sparen. Dies funktioniert auch in C
12Me21,
1
Mit können Sie 4 weitere Bytes sparen z=*(int*)x^*(int*)y;.
Arnauld
1
Mit GCC-Erweiterungen, 54 Bytes:#define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
Nishioka
2
Ist es zulässig, eine der Eingaben als Ausgabe zu verwenden, da Sie Zeiger verwenden? Wenn ja, könnten Sie schreiben (*(int*)x^=*(int*)y).
Neil
1
Unter Berücksichtigung von Neils Vorschlag würden es 48 Bytes werden:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka
9

ARM Thumb Machine Code, 6 4 Bytes

48 40 70 47

In Montage:

EORS R0, R1; Exklusiv Oder der ersten beiden Parameter, Ergebnis im Rückgaberegister speichern
BX LR; Verzweige zu dem im Link Register gespeicherten Wert (Absenderadresse)

Gemäß der Standardkonvention für den Aufruf von Arm werden die ersten beiden Parameter in den Registern R0 und R1 übergeben, die Ergebnisse werden in R0 zurückgegeben und LR enthält die Rücksprungadresse. Angenommen, Sie verwenden das Soft-Float-ABI mit 32-Bit-Floats, wird die gewünschte Operation in 4 Bytes ausgeführt.

-2 Bytes dank Cody Gray

Sir_Lagsalot
quelle
2
Wäre es möglich, EORS r0, r1stattdessen zu verwenden , um 2 Bytes zu sparen? Dies ist nur eine 2-Byte-Anweisung ( 48 40) im Vergleich zu Ihrer 4-Byte -Anweisung EOR. Sie zielen bereits auf Thumb, daher sollte dies, soweit ich sehen kann, gut funktionieren. Der einzige Unterschied besteht darin, dass Status-Flags aktualisiert werden. Diese Nebenwirkung ist Ihnen in diesem Fall jedoch egal.
Cody Grey
2
Sie sollten angeben, dass dies die Soft-Float-ABI verwendet, die FP-Args in Ganzzahlregistern übergibt, nicht in VFP / NEON s0und s1.
Peter Cordes
6

Python 3 + numpy, 75 59 Bytes

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

Probieren Sie es online!

Definiert ein Lambda, das zwei numpy float32-Arrays als Argumente verwendet und ein numpy float32-Array zurückgibt.

Vielen Dank an @ShadowRanger für das Speichern von 14 Bytes und Joel für weitere 2!

Wenn der Import abgebrochen werden kann (da mein Lambda selbst Methoden für numpy-Objekte aufruft und keine grundlegenden numpy-Funktionen), könnte ich weitere 13 Bytes einsparen. Ich bin mir nicht sicher, was die Standardregeln für den Golf-Code angeht.

Nick Kennedy
quelle
Es ist kürzer als die Antworten von Jelly und Ruby. Nett!
Eric Duminil
Sie können 27 Bytes einsparen (auf 48 Bytes reduzieren), indem Sie den Import vollständig entfernen (nehmen Sie einfach an, der Anrufer hat Sie übergeben, numpy.float32damit Sie seine Methoden verwenden können) und beide int32Verwendungen durch 'i'und die float32Verwendung durch ersetzen 'f'. der dtypeParameter kann eine Zeichenfolge sein , die auf den realen umgewandelt werden dtypefür Dich und bequem, 'i'und 'f'es rechtliche Möglichkeiten , diese dtypes zu machen, das die Notwendigkeit für die Funktion Import entfernt numpyZeug in seinen Namensraum überhaupt. Ich numpy
bin
Ich dachte, die Importe müssten einbezogen werden, bin mir aber nicht sicher. Danke für den Tipp bezüglich der dtypes!
Nick Kennedy
@ NickKennedy: Ja, wenn der Import erforderlich ist, werden nur 8 Bytes (zwei von int32bis 'i', vier von float32bis 'f') eingespart , aber das ist immer noch etwas. Wenn der Import unbedingt erforderlich ist, können Sie ihn einfach in ändern, um import numpyzu bestätigen, dass das Paket vorhanden ist, ohne mithilfe from numpy import*von Namen daraus zu extrahieren. Das würde Ihnen weitere sechs Bytes bringen, also insgesamt 61 Bytes.
ShadowRanger
6

Jelly + Numpy, 89 77 Bytes

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

Probieren Sie es online!

Hat die zweifelhafte Ehre, länger zu sein als der Python 3-Code, den es reproduziert, hauptsächlich wegen der Notwendigkeit, zu / von numpy objecte zu konvertieren und der Tatsache, dass numpy nicht von Jelly geladen wird, so dass das __import__()eingebaute verwendet werden muss.

Ein monadischer Link, der die beiden Floats als Liste als Argument verwendet und einen Float zurückgibt.

Wertet den folgenden Python 3-Code aus:

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

wo xund ywerden durch die Eingabe ersetzt.

Nick Kennedy
quelle
5

APL (Dyalog Unicode) , 14 Byte SBCS

Volles Programm. Fordert zur Eingabe einer 1-Spalten-Matrix aus zwei 64-Bit-Gleitkommazahlen nach IEEE 754 (binary64) von stdin auf. Gibt eine solche Nummer als Standard aus.

645DR≠⌿11DR

Probieren Sie es online!

 prompt (Zahlen, die zu Nicht-Floats zusammenfallen, können mit der Funktion zu Floats gezwungen werden ⊃⊢⎕DR⍨645,⍨⎕DR)

11⎕DR Umrechnen in 1-Bit - Binär (1) D ata R ePresentation (2-Reihe, 64-Spalten - Matrix)

≠⌿ vertikale XOR-Reduktion

645⎕DR Umrechnen in 64-Bit - Schwimmers (5) D ata R ePresentation (single - Nummer)

Adam
quelle
4

VAX BASIC (später VMS BASIC, dann Compaq Basic) , 11 Byte

H = F XOR G

Scheint mir ein bisschen albern zu sein, offensichtlich werden ältere Sprachen besser abschneiden, weil sie sich nicht so viele Sorgen um das starke Tippen machten.

RBarryYoung
quelle
1
Willkommen auf der Seite und schöne erste Antwort! Ich habe einen
scheinbar irrelevanten
3

Oktave , 59 Bytes

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

Probieren Sie es online!

Typecast ist die MATLAB / Octave-Methode zum Casting, ohne die zugrunde liegenden Bits zu ändern. Dies ist erforderlich, da bitxornur Ganzzahlen verarbeitet werden können. Keine Ahnung, warum sie niemals Gleitkommazahlen implementiert haben, obwohl Sie das AssumedTypeals drittes Argument explizit angeben können bitxor. Ich denke, die einzige Verwendung ist Freizeitprogrammierung.

Sanchises
quelle
Bitweises Stoppen von FP-Bitmustern ist in Assemblersprachen nützlich, um Dinge mit dem Vorzeichenbit zu tun, oder selten, um eine Ganzzahl als Teil einer exp()Implementierung in das Exponentenfeld zu stopfen . Ich gehe aber davon aus, dass Octave bereits Funktionen / Operatoren für Copysign und Negation hat. Und sie interessieren sich nicht für Mikrooptimierungen wie die Verwendung von AND (mit einer konstanten Maske) und XOR, um das Vorzeichen eines Werts basierend auf dem Vorzeichen eines anderen Werts bedingt umzukehren. In einem echten Optimierungsprojekt in asm (tatsächlich C mit AVX intrinsics) habe ich XOR von Floats verwendet und dann das Vorzeichenbit betrachtet, um cmp gegen Null zu vermeiden.
Peter Cordes
2

C 23 Bytes

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

Probieren Sie es online!

Dies könnte etwas unbeständig sein. es braucht die Zeiger auffloat s als Zeiger auf ints.

Es funktioniert jedoch (das ist immerhin C).

Dies nutzt akzeptable Eingaben aus, indem ein Zeiger auf die Variable gesetzt und an Ort und Stelle geändert wird. Es wird kein (verwendbarer) Wert zurückgegeben.

JL2210
quelle
2

JavaScript (Node.js) ,  105  101 Byte

Kürzere Node-Version vorgeschlagen von @Neil
Dank @ShieruAsakoto wurden 4 weitere Bytes gespeichert

Übernimmt die Eingabe als (x)(y).

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

Probieren Sie es online!


JavaScript (ES6), 115 Byte

Nimmt die Eingabe als Array von 2 Floats.

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

Probieren Sie es online!

Arnauld
quelle
FYI Knotens Bufferspeichert ein paar Bytes: a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE()).
Neil
@ Neil Danke! (2 weitere Bytes durch Verwendung einer Funktion anstelle von gespeichert map)
Arnauld
1
Den Abwurf newin new Buffer(4)Arbeit sollte auch iirc
Shieru Asakoto
1

Wolfram Mathematica , 50 Bytes

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

Ich bin zwar der festen Überzeugung, dass dies besser funktioniert, aber die beiden zusätzlichen Argumente in der RealDigitsFunktion scheinen notwendig zu sein, um ein korrektes Ergebnis zu erzielen .

Probieren Sie es online!

Polfosol ఠ_ఠ
quelle
1

Lua , 73 Bytes

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

Probieren Sie es online!

Dieser Code setzt 4-Byte-Ganzzahlen ohne Vorzeichen und Gleitkommazahlen voraus, für die die Konfiguration aktiviert ist tio.run. Führen Sie als vollständiges Programm mit Eingaben als Argumente aus.

val sagt Reinstate Monica
quelle
1

Ruby , 78 67 Bytes

-11 Bytes dank @grawity.

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

Probieren Sie es online!

Input ist ein Array von zwei Floats.

Eric Duminil
quelle
x.map{|v|[v].pack(?g).unpack(?N)[0]}x.pack("gg").unpack("NN")
user1686
@grawity: Super, vielen Dank! Der Code ist jedoch immer noch länger als in Python. : - /
Eric Duminil
1

Java (JDK) , 109 76 Bytes

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

Probieren Sie es online!

Es ist schon eine Weile her, dass ich in Java Golf gespielt habe und ich bin mir nicht sicher, ob ich die Deklaration auf der LHS als Teil der Byteanzahl benötige? Wenn DoubleBinaryOperator verwendet würde, wäre die LHS kürzer, aber die RHS müsste Double.doubleToLongBits und Double.longBitsToDouble verwenden, das ist also tatsächlich länger.

Vielen Dank an Neil für die erheblichen Einsparungen bei der Byteanzahl!

David Conrad
quelle
1
IIRC benötigen Sie die Zuweisung nicht einmal als Teil der Byteanzahl, sondern nur als Teil einer Testsuite, die Sie in Ihrem Online-Test enthalten könnten! Header.
Neil
@ Neil Danke! Das macht einen großen Unterschied!
David Conrad
0

Sauber , 36 Bytes

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

Probieren Sie es online!

Zum Glück die Real und Int-Typen auf 64-Bit-Plattformen gleich groß ...
Erfordert leider eine vollständige Signatur, da sich das Diagramm sonst in eine Brezel verwandelt und alles fehlerfrei funktioniert.

Οurous
quelle