Zmienny punkt XOR


15

Twoje zadanie jest dość proste. Biorąc pod uwagę dwa zmiennoprzecinkowe, bitowo x lub ich reprezentację binarną, i wysyłaj jako zmiennoprzecinkowe.

Na przykład,

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

Ograniczenia / wyjaśnienia:

  • Wejścia / wyjścia można podać dowolną dogodną metodą .
  • Program może być pełnym programem lub tylko funkcją; albo jedno jest w porządku.
  • Typ float może mieć dowolny rozmiar, ale minimalny rozmiar to 2 bajty.
  • Standardowe luki są zabronione.
  • Najkrótszy kod wygrywa.

2
Czy lista boolowska liczy się jako wygodna metoda?
Adám

23
„binarna reprezentacja” liczby zmiennoprzecinkowej jest niezwykle niejednoznaczna. Musisz określić, jakiej reprezentacji używasz. Istnieje nieskończona liczba przedstawień, w tym liczba skończona używana już przez życie na tej planecie, niektóre z nich są bardziej popularne niż inne, takie jak IEEE 754
Reversed Engineer

7
To pytanie byłoby bardziej interesujące jako „xor wartości ” niż „xor reprezentacje”. Ten ostatni jest oczywiście identyczny z „x lub dwiema 32-bitowymi liczbami całkowitymi” w dowolnym języku, w którym brakuje systemu czcionek lub dopuszcza pisanie czcionek, a zatem jest dość nudny ...
R .. GitHub STOP HELPING ICE

5
Czy musimy obsługiwać nieskończoność, podnormalne lub ujemne 0 jako dane wejściowe lub wyjściowe?
Grimmy,

3
@Mark: Nie, jak napisano, pytanie dotyczy tylko ich reprezentacji, niezależnie od tego, jakie są te reprezentacje. Wynik zależy od formatu zmiennoprzecinkowego, ale algorytm jest zawsze pojedynczą instrukcją xor reprezentacji, co jest dość nudne.
R .. GitHub ZATRZYMAJ LÓD

Odpowiedzi:


53

kod maszynowy x86-64, 4 bajty

0f 57 c1 c3

W montażu:

xorps xmm0, xmm1
ret

Jest to wywoływalna funkcja, która przyjmuje dwa zmiennoprzecinkowe lub podwajające się argumenty (in xmm0i xmm1) i zwraca zmiennoprzecinkowe lub double (in xmm0).

Jest to zgodne z konwencjami wywoływania zarówno Windows x64, jak i x86-64 SysV ABI, i działa zarówno dla liczb zmiennoprzecinkowych, jak i podwójnych. (Są przekazywane / zwracane w niskich 4 lub 8 bajtach rejestrów XMM).


12

C ++ (gcc) , 74 32 bajty

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

Wypróbuj online!

Nie grałem wcześniej w C ++, więc jestem wdzięczny wszystkim, którzy pomogli zmniejszyć rozmiar kodu o połowę! Makro, które przejmuje wskaźniki do dwóch liczb zmiennoprzecinkowych jako argumenty i zmodyfikowało pierwsze, aby zwrócić wynik.

Dzięki @ 12Me1 za uratowanie 2 bajtów i @Arnauld za uratowanie 4! Dzięki @Nishioka za uratowanie kolejnych 14, @Neil kolejne 6, a @AZTECCO i @Nishioka kolejne 11! Dzięki @PeterCordes za zapisanie 5 bajtów!


1
Możesz usunąć podziały linii, aby zapisać 2 znaki, a to działa również w C
Me

1
Możesz zapisać 4 kolejne bajty za pomocą z=*(int*)x^*(int*)y;.
Arnauld

1
Z rozszerzeniami gcc, 54 bajty:#define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
Nishioka

2
Skoro używasz wskaźników, czy legalne jest używanie jednego z danych wejściowych jako danych wyjściowych? Jeśli tak, możesz napisać (*(int*)x^=*(int*)y).
Neil

1
Biorąc pod uwagę sugestię @ Neila, uzyskałby 48 bajtów:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka,

9

Kod maszynowy ARM Thumb, 6 4 bajtów

48 40 70 47

W montażu:

EORS R0, R1; Wyłącznie Lub z pierwszych dwóch parametrów, zapis wyników w rejestrze zwrotnym
BX LR; Rozgałęzienie do wartości zapisanej w rejestrze linków (adres zwrotny)

Zgodnie ze standardową konwencją wywoływania uzbrojenia pierwsze dwa parametry są przekazywane do rejestrów R0 i R1, wyniki są zwracane w R0, a LR przechowuje adres zwrotny. Zakładając, że używasz miękkiego pływaka ABI z 32-bitowymi pływakami, wykona on pożądaną operację w 4 bajtach.

-2 bajty dzięki Cody Grayowi


2
Czy EORS r0, r1zamiast tego można by użyć do zapisania 2 bajtów? To tylko 2-bajtowa instrukcja ( 48 40) w porównaniu do 4-bajtowej EOR. Celujesz już w Thumb, więc, o ile mi wiadomo, to powinno działać dobrze. Jedyną różnicą jest to, że aktualizuje flagi stanu, ale w tym przypadku nie obchodzi Cię ten efekt uboczny.
Cody Gray

2
Powinieneś określić, że używa to soft-float ABI, który przekazuje argumenty FP w rejestrach liczb całkowitych, a nie VFP / NEON s0i s1.
Peter Cordes,

6

Python 3 + numpy, 75 59 bajtów

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

Wypróbuj online!

Definiuje lambda, która przyjmuje dwie tablice float32 numpy jako argumenty i zwraca tablicę float32 numpy.

Dzięki @ShadowRanger za zapisanie 14 bajtów, a Joel kolejne 2!

Jeśli import może zostać porzucony (ponieważ moja lambda sama wywołuje metody na obiektach numpy zamiast jakichkolwiek podstawowych funkcji numpy), mógłbym zapisać kolejne 13 bajtów. Nie jestem tego pewien od standardowych zasad golfa.


Jest krótszy niż odpowiedzi Jelly i Ruby. Ładny!
Eric Duminil,

Możesz ogolić 27 bajtów (upuszczając go do 48 bajtów), całkowicie usuwając import (zakładając, że dzwoniący przekazał ci numpy.float32, abyś mógł użyć ich metod) i zastępując oba int32zastosowania 'i'i float32użycie 'f'; dtypeparametr może być ciągiem znaków, który zostaje przekształcony na prawdziwe dtypedla ciebie, i wygodnie, 'i'i 'f'są legalne sposoby, aby te dtypes, co eliminuje potrzebę funkcji do importowania numpyrzeczy do swojej przestrzeni nazw w ogóle. Nie jestem pewien, czy Code Golf może usunąć import, ale nadal przyjmuje numpydane wejściowe ...
ShadowRanger


Myślałem, że należy uwzględnić import, ale nie jestem pewien. Dzięki za wskazówkę dotyczącą typów!
Nick Kennedy

@NickKennedy: Tak, jeśli import jest wymagany, zapisuje tylko 8 bajtów (dwa z każdego int32do 'i', cztery z float32do 'f'), ale to wciąż coś. Jeśli import jest ściśle wymagany, możesz go po prostu zmienić, import numpyaby potwierdzić, że pakiet istnieje, bez from numpy import*konieczności wyodrębniania z niego nazw. To da ci kolejne sześć bajtów, łącznie do 61 bajtów.
ShadowRanger

6

Galaretka + numpy, 89 77 bajtów

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

Wypróbuj online!

Ma wątpliwy zaszczyt bycia dłuższym niż kod, który odtwarza w Pythonie 3, głównie ze względu na potrzebę konwersji na / z obiektu numpy i faktu, że Jelly nie jest ładowany przez Jelly, więc __import__()należy użyć wbudowanego.

Monadyczny link przyjmujący oba argumenty jako listę jako argument i zwracający liczbę zmiennoprzecinkową.

Ocenia następujący kod Python 3:

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

gdzie xi ysą podstawione przez dane wejściowe.


5

APL (Dyalog Unicode) , 14 bajtów SBCS

Pełny program Monity o 1-kolumnową macierz dwóch 64-bitowych liczb zmiennoprzecinkowych IEEE 754 (binary64) ze standardowego wejścia. Drukuje jeden taki numer na standardowe wyjście.

645DR≠⌿11DR

Wypróbuj online!

 monit (liczby, które zwinięte są na zmiennoprzecinkowe, można zmusić do przekształcenia w zmiennoprzecinkowe za pomocą funkcji ⊃⊢⎕DR⍨645,⍨⎕DR)

11⎕DR konwertuj na 1-bitowy plik binarny (1) D ata R reprezentacja (macierz 2-rzędowa, 64-kolumnowa)

≠⌿ pionowa redukcja XOR

645⎕DR konwertuj na 64-bitową liczbę zmiennoprzecinkową (5) D ata R eprezentacja (pojedynczy numer)


4

VAX BASIC (później VMS BASIC, następnie Compaq Basic) , 11 bajtów

H = F XOR G

Wydaje mi się to trochę głupie, oczywiście, starsze języki poradzą sobie lepiej, ponieważ nie martwią się tak bardzo o problemy z pisaniem na maszynie.


1
Witamy na stronie i fajna pierwsza odpowiedź! Zredagowałem coś, co wydaje się być obcym nagłówkiem, ale jeśli nie, możesz go edytować z powrotem wraz z wszelkimi towarzyszącymi mu informacjami
Cairn coinheringaahing

3

Oktawa , 59 bajtów

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

Wypróbuj online!

Typecast to metoda rzutowania MATLAB / Octave bez zmiany podstawowych bitów. Jest to wymagane, ponieważ bitxordziała tylko na liczbach całkowitych. Nie mam pojęcia, dlaczego nigdy nie zaimplementowali liczb zmiennoprzecinkowych, nawet jeśli możesz jawnie podać AssumedTypetrzeci argument bitxor. Chyba jedynym zastosowaniem jest programowanie rekreacyjne.


Bitowe wstawianie wzorców bitów FP jest przydatne w języku asemblera do robienia rzeczy z bitem znakowym lub rzadko do wypychania liczb całkowitych w polu wykładniczym jako część exp()implementacji. Ale zakładam, że Octave ma już funkcje / operatory do copysign i negacji. I nie dbają o mikrooptymalizacje, takie jak użycie AND (ze stałą maską), a następnie XOR, aby warunkowo odwrócić znak jednej wartości na podstawie znaku innej. W prawdziwym projekcie optymalizacyjnym w asm (właściwie C z wewnętrznymi elementami AVX) użyłem XOR pływaków, a następnie patrzyłem na bit znaku, aby uniknąć cmp w stosunku do zera.
Peter Cordes,




2

C, 23 bajty

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

Wypróbuj online!

To może być nieco zmienne; przyjmuje wskaźniki do floats jako wskaźniki do ints.

Jednak to działa (w końcu jest to C).

Wykorzystuje to akceptowalne dane wejściowe, biorąc wskaźnik do zmiennej i modyfikując ją w miejscu. Żadna (użyteczna) wartość nie jest zwracana.


2

JavaScript (Node.js) ,  105  101 bajtów

Krótsza wersja węzła sugerowana przez @Neil
Zaoszczędź 4 bajty dzięki @ShieruAsakoto

Pobiera dane wejściowe jako (x)(y).

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

Wypróbuj online!


JavaScript (ES6), 115 bajtów

Pobiera dane wejściowe jako tablicę 2 liczb zmiennoprzecinkowych.

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

Wypróbuj online!


FYI węzła Bufferoszczędza kilka bajtów: a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE()).
Neil

@Neil Thanks! (zapisano jeszcze 2 bajty przy użyciu funkcji zamiast map)
Arnauld

1
Upuszczenie newin new Buffer(4)powinny również działać IIRC
Shieru Asakoto


1

Lua , 73 bajty

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

Wypróbuj online!

Ten kod zakłada 4-bajtowe liczby całkowite bez znaku i zmiennoprzecinkowe, na których konfiguracja jest włączona tio.run. Uruchom jako pełny program z danymi wejściowymi jako argumentami.


1

Rubinowy , 78 67 bajtów

-11 bajtów dzięki @grawity.

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

Wypróbuj online!

Dane wejściowe to tablica dwóch liczb zmiennoprzecinkowych.


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

@grawity: Super, dziękuję bardzo! Kod jest jednak wciąż dłuższy niż w Pythonie. : - /
Eric Duminil,

1

Java (JDK) , 109 76 bajtów

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

Wypróbuj online!

Minęło trochę czasu, odkąd grałem w Javę i nie jestem pewien, czy potrzebuję deklaracji na LHS jako części liczby bajtów? Gdyby użył DoubleBinaryOperator, LHS byłby krótszy, ale RHS musiałby użyć Double.doubleToLongBits i Double.longBitsToDouble, więc to faktycznie dłużej.

Dzięki Neil za znaczne oszczędności w liczbie bajtów!


1
IIRC nie potrzebujesz nawet przypisania jako części liczby bajtów, tylko jako część dowolnego zestawu testów, który możesz uwzględnić w Wypróbuj online! nagłówek.
Neil

@Neil Dziękujemy! To duża różnica!
David Conrad

0

Czysty , 36 bajtów

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

Wypróbuj online!

Na szczęście Reali Inttypy mają te same rozmiary na platformach 64-bitowych ...
Niestety wymaga pełnego podpisu, w przeciwnym razie wykres zamieni się w precla i wszystko się nie powiedzie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.