Floating Point XOR


15

Tugas Anda cukup sederhana. Diberi dua float, bitwise untuk representasi binernya, dan mengeluarkannya sebagai float.

Sebagai contoh,

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

Batasan / klarifikasi:

  • Input / output dapat diberikan dengan metode apa pun yang mudah .
  • Program dapat berupa program lengkap atau hanya fungsi; baik baik saja.
  • Tipe float dapat berupa ukuran apa saja, tetapi ukuran minimumnya adalah 2 byte.
  • Celah standar dilarang.
  • Kode terpendek menang.

2
Apakah daftar Boolean dianggap sebagai metode yang nyaman?
Adám

23
"Representasi biner" dari float sangat ambigu. Anda harus menentukan representasi yang Anda gunakan. Ada jumlah representasi yang tak terbatas, termasuk jumlah terbatas yang sudah digunakan oleh kehidupan di planet ini, beberapa menjadi lebih populer daripada yang lain, seperti IEEE 754
Reversed Engineer

7
Pertanyaan ini akan lebih menarik sebagai "xor nilai " daripada "xor representasi". Yang terakhir ini tentu saja identik dengan "xor dua bilangan bulat 32-bit" dalam bahasa yang tidak memiliki sistem jenis atau mengakui jenis punning, dan dengan demikian cukup membosankan ...
R .. GitHub BERHENTI MEMBANTU ICE

5
Apakah kita harus menangani tak terhingga, subnormal, atau negatif 0, baik sebagai input atau output?
Grimmy

3
@ Mark: Tidak, seperti yang ditulis, pertanyaannya adalah hanya tentang mengubah perwakilan mereka, apa pun representasi itu. Hasilnya tergantung pada format floating point tetapi algoritme selalu merupakan instruksi tunggal atau tunggal pada representasi, yang cukup membosankan.
R .. GitHub BERHENTI MEMBANTU ICE

Jawaban:


53

kode mesin x86-64, 4 byte

0f 57 c1 c3

Dalam perakitan:

xorps xmm0, xmm1
ret

Ini adalah fungsi yang bisa dipanggil yang membutuhkan dua float atau double sebagai argumen (dalam xmm0dan xmm1) dan mengembalikan float atau ganda (dalam xmm0).

Itu cocok dengan konvensi pemanggilan Windows x64 dan SysV ABI x86-64, dan berfungsi untuk float serta ganda. (Mereka lulus / dikembalikan dalam register XMM 4 atau 8 byte yang rendah).


12

C ++ (gcc) , 74 32 byte

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

Cobalah online!

Saya belum pernah bermain golf di C ++ jadi saya berterima kasih kepada semua yang telah membantu membagi dua ukuran kode! Makro yang mengambil pointer ke dua mengapung sebagai argumennya dan memodifikasi yang pertama untuk mengembalikan hasilnya.

Terima kasih kepada @ 12Me1 untuk menghemat 2 byte dan @Arnauld untuk menghemat 4! Terima kasih kepada @Nishioka karena telah menyimpan 14 lainnya, @Neil tambahan 6 dan @AZTECCO dan @Nishioka 11 lainnya! Terima kasih kepada @PeterCordes untuk menghemat 5 byte!


1
Anda dapat menghapus linebreak untuk menyimpan 2 karakter, dan ini juga berfungsi di C
12Me21

1
Anda dapat menyimpan 4 byte lebih banyak dengan z=*(int*)x^*(int*)y;.
Arnauld

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

2
Karena Anda menggunakan pointer, apakah sah menggunakan salah satu input sebagai output? Jika demikian, Anda bisa menulis (*(int*)x^=*(int*)y).
Neil

1
Mempertimbangkan saran @ Neil itu akan mencapai 48 byte:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka

9

ARM Thumb Machine Code, 6 4 Bytes

48 40 70 47

Dalam perakitan:

EORS R0, R1; Eksklusif Atau dari dua param pertama, toko menghasilkan register pengembalian
BX LR; Cabang ke nilai yang disimpan dalam Daftar Tautan (Alamat pengembalian)

Di bawah konvensi standar pemanggilan Arm, dua parameter pertama dilewatkan dalam register R0 dan R1, hasilnya dikembalikan dalam R0, dan LR memegang alamat pengirim. Dengan asumsi Anda menggunakan ABI float lunak dengan float 32 bit, ini akan melakukan operasi yang diinginkan dalam 4 byte.

-2 byte berkat Cody Grey


2
Apakah mungkin untuk menggunakan EORS r0, r1sebagai gantinya, untuk menghemat 2 byte? Itu hanya instruksi 2-byte ( 48 40), dibandingkan dengan 4-byte Anda EOR. Anda sudah menargetkan Jempol, jadi ini akan berfungsi dengan baik, sejauh yang saya bisa lihat. Satu-satunya perbedaan adalah pembaruan flag status, tetapi Anda tidak peduli tentang efek samping dalam kasus ini.
Cody Grey

2
Anda harus menentukan bahwa ini menggunakan ABI soft-float yang melewatkan FP args dalam register integer, bukan VFP / NEON s0dan s1.
Peter Cordes

6

Python 3 + numpy, 75 59 byte

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

Cobalah online!

Mendefinisikan lambda yang menggunakan dua array float32 numpy sebagai argumennya dan mengembalikan array float32 numpy.

Terima kasih kepada @ShadowRanger untuk menghemat 14 byte, dan Joel 2 lebih lanjut!

Jika impor dapat dijatuhkan (karena lambda saya sendiri memanggil metode pada objek numpy daripada fungsi dasar numpy), saya bisa menyimpan 13 byte lebih lanjut. Saya tidak yakin tentang ini dari aturan standar kode golf.


Ini lebih pendek dari jawaban Jelly dan Ruby. Bagus!
Eric Duminil

Anda dapat mengurangi 27 byte (menjatuhkannya menjadi 48 byte) dengan menghapus impor seluruhnya (anggap saja penelepon melewati Anda numpy.float32sehingga Anda dapat menggunakan metode mereka) dan mengganti kedua int32penggunaan dengan 'i'dan float32penggunaan dengan 'f'; yang dtypeparameter dapat berupa string yang akan dikonversi ke nyata dtypeuntuk Anda, dan nyaman, 'i'dan 'f'cara hukum untuk membuat orang-orang dtypes, yang menghilangkan kebutuhan untuk fungsi untuk impor numpybarang ke namespace sama sekali. Tidak yakin apakah Code Golf legal untuk menghapus impor tetapi masih menganggap numpyinput ...
ShadowRanger


Saya pikir impor harus dimasukkan, tetapi saya tidak yakin. Terima kasih atas tipnya kembali dtypes!
Nick Kennedy

@NickKennedy: Ya, jika impor diperlukan, itu hanya menghemat 8 byte (masing-masing dua dari int32ke 'i'empat dari float32ke 'f'), tapi itu masih sesuatu. Jika impor benar-benar diperlukan, Anda bisa mengubahnya import numpyuntuk menegaskan paket itu ada, tanpa menggunakan from numpy import*untuk mengekstrak nama darinya. Itu akan memberi Anda enam byte lagi, hingga total 61 byte.
ShadowRanger

6

Jelly + numpy, 89 77 byte

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

Cobalah online!

Memiliki kehormatan yang meragukan karena lebih panjang dari kode Python 3 yang direproduksi, sebagian besar karena kebutuhan untuk mengkonversi ke / dari objek numpy dan fakta bahwa numpy tidak dimuat oleh Jelly sehingga __import__()built-in harus digunakan.

Tautan monadik mengambil dua pelampung sebagai daftar sebagai argumennya dan mengembalikan pelampung.

Mengevaluasi kode Python 3 berikut:

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

di mana xdan ydiganti dengan input.


5

APL (Dyalog Unicode) , 14 byte SBCS

Program lengkap. Anjuran untuk matriks 1-kolom dari dua nomor floating-point IEEE 754 64-bit (binary64) dari stdin. Mencetak satu nomor seperti itu ke stdout.

645DR≠⌿11DR

Cobalah online!

 prompt (angka-angka yang runtuh menjadi non-mengapung dapat dipaksa menjadi mengapung dengan fungsi ⊃⊢⎕DR⍨645,⍨⎕DR)

11⎕DR dikonversi ke 1-bit Binary (1) D ata R epresentation (2-row, 64-matrix matrix)

≠⌿ pengurangan XOR vertikal

645⎕DR dikonversi ke float 64-bit (5) D ata R epresentation (nomor tunggal)


4

VAX BASIC (kemudian VMS BASIC, kemudian Compaq Basic) , 11 byte

H = F XOR G

Bagi saya agak konyol, jelas, bahasa yang lebih tua akan lebih baik karena mereka tidak terlalu khawatir tentang masalah pengetikan yang kuat.


1
Selamat datang di situs dan jawaban pertama yang bagus! Saya telah mengedit apa yang tampak sebagai header yang asing, tetapi jika tidak merasa bebas untuk mengeditnya kembali, bersama dengan informasi yang menyertainya
caird coinheringaahing

3

Oktaf , 59 byte

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

Cobalah online!

Typecast adalah cara casting MATLAB / Oktaf tanpa mengubah bit yang mendasarinya. Ini diperlukan karena bitxorhanya berfungsi pada bilangan bulat. Tidak tahu mengapa mereka tidak pernah menerapkan angka floating point, meskipun Anda dapat secara eksplisit menentukan AssumedTypeargumen ketiga bitxor. Saya kira satu-satunya penggunaan adalah program rekreasi.


Bitwise stuff pada pola bit FP berguna dalam bahasa assembly untuk melakukan sesuatu dengan bit sign, atau jarang memasukkan integer ke dalam bidang eksponen sebagai bagian dari exp()implementasi. Tapi saya menganggap Octave sudah memiliki fungsi / operator untuk copysign dan negasi. Dan mereka tidak peduli tentang optimasi mikro seperti menggunakan AND (dengan mask konstan) kemudian XOR untuk secara kondisional membalik tanda dari satu nilai berdasarkan tanda yang lain. Dalam proyek optimasi nyata dalam asm (sebenarnya C dengan AVX intrinsik) Saya telah menggunakan XOR mengapung kemudian melihat tanda bit untuk menghindari cmp terhadap nol.
Peter Cordes




2

C, 23 byte

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

Cobalah online!

Ini mungkin agak licik; dibutuhkan pointer ke floats sebagai pointer ke ints.

Namun, itu berhasil (ini C setelah semua).

Ini mengambil keuntungan dari input yang dapat diterima dengan mengambil pointer ke variabel dan mengubahnya di tempat. Tidak ada nilai (dapat digunakan) yang dikembalikan.


2

JavaScript (Node.js) ,  105  101 byte

Versi Node yang lebih pendek disarankan oleh @Neil
Disimpan 4 byte lebih banyak berkat @ShieruAsakoto

Mengambil input sebagai (x)(y).

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

Cobalah online!


JavaScript (ES6), 115 byte

Mengambil input sebagai array yang terdiri dari 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))

Cobalah online!


FYI Node ini Buffermenyimpan beberapa byte: a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE()).
Neil

@Neil Terima kasih! (disimpan 2 byte lebih banyak dengan menggunakan fungsi alih-alih map)
Arnauld

1
Menjatuhkan newin new Buffer(4)juga harus bekerja pada iirc
Shieru Asakoto


1

Lua , 73 byte

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

Cobalah online!

Kode ini mengasumsikan bilangan bulat unsigned 4-byte dan mengapung yang merupakan konfigurasi tio.run. Jalankan sebagai program lengkap dengan input sebagai argumen.


1

Ruby , 78 67 byte

-11 byte terima kasih kepada @grawity.

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

Cobalah online!

Input adalah array dari dua float.


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

@ kegembiraan: Luar biasa, terima kasih banyak! Kode ini masih lebih lama daripada di Python. : - /
Eric Duminil

1

Jawa (JDK) , 109 76 byte

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

Cobalah online!

Sudah lama sejak saya bermain golf di Jawa dan saya tidak yakin apakah saya perlu deklarasi pada LHS sebagai bagian dari jumlah byte? Jika menggunakan DoubleBinaryOperator LHS akan lebih pendek, tetapi RHS harus menggunakan Double.doubleToLongBits dan Double.longBitsToDouble, jadi itu sebenarnya lebih lama.

Terima kasih kepada Neil untuk penghematan besar pada jumlah byte!


1
IIRC Anda bahkan tidak perlu penugasan sebagai bagian dari jumlah byte, hanya sebagai bagian dari setiap rangkaian tes yang mungkin Anda sertakan dalam Cobalah secara online! tajuk.
Neil

@Neil Terima kasih! Itu membuat perbedaan besar!
David Conrad

0

Bersih , 36 byte

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

Cobalah online!

Untungnya jenis Realdan Intukurannya sama pada platform 64-bit ...
Sayangnya memerlukan tanda tangan lengkap jika tidak grafik berubah menjadi pretzel dan semuanya segfault.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.