Kayan Nokta XOR


16

Göreviniz oldukça basit. Verilen iki şamandıra, bunların ikili gösterimini bitsel olarak xorveya, ve bunu şamandıra olarak çıktı.

Örneğin,

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

Kısıtlamalar / açıklamalar:

  • Giriş / çıkış herhangi bir uygun yöntemle verilebilir .
  • Program tam bir program veya sadece bir fonksiyon olabilir; her ikisi de iyidir.
  • Şamandıra türü herhangi bir boyutta olabilir, ancak minimum boyut 2 bayttır.
  • Standart boşluklar yasaktır.
  • En kısa kod kazanır.

2
Boole listesi uygun bir yöntem olarak sayılıyor mu?
Adam

23
Bir şamandıranın "ikili gösterimi" son derece belirsizdir. Hangi temsili kullandığınızı tanımlamanız gerekir. IEEE 754
Tersine Mühendis

7
Bu soru, "xveya gösterimleri" yerine " değerleri veya değerleri " olarak daha ilginç olacaktır . İkincisi elbette bir tür sistem yoksun veya tip punning kabul eden herhangi bir dilde "x veya iki 32 bit tamsayı" ile aynıdır ve bu nedenle oldukça sıkıcı ...
R .. GitHub DURDURMAK ICE

5
Sonsuzluk, alt normaller veya negatif 0'ı girdi veya çıktı olarak ele almamız gerekiyor mu?
Grimmy

3
@Mark: Hayır, yazıldığı gibi soru, temsiller ne olursa olsun, temsiliyetlerini xor'lamakla ilgilidir. Sonuç kayan nokta biçimine bağlıdır, ancak algoritma her zaman temsilde tek bir xor komutudur ve bu oldukça sıkıcıdır.
R .. GitHub BUZA YARDIMCI DURDUR

Yanıtlar:


53

x86-64 makine kodu, 4 bayt

0f 57 c1 c3

Montajda:

xorps xmm0, xmm1
ret

Bu, iki yüzer veya iki kez değişken (in xmm0ve xmm1) olarak alan ve bir float veya double (in xmm0) döndüren çağrılabilir bir işlevdir .

Bu, hem Windows x64 hem de x86-64 SysV ABI'nin çağrı kurallarıyla eşleşir ve şamandıralar ve çiftler için çalışır. (XMM kayıtlarının düşük 4 veya 8 baytında iletilir / döndürülür).


12

C ++ (gcc) , 74 32 bayt

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

Çevrimiçi deneyin!

Daha önce C ++ golf değil bu yüzden kod boyutunu yarıya yardımcı olan herkese minnettarım! İşaretçileri argüman olarak iki kayan noktaya götüren ve sonucu döndürmek için ilkini değiştiren bir makro.

2 bayt tasarruf için @ 12Me1 ve 4 tasarruf için @Arnauld sayesinde! @Nishioka'ya başka bir 14 kurtardığı için teşekkürler, @Neil a 6 ve @AZTECCO ve @Nishioka başka 11! 5 bayt tasarruf için @PeterCordes'a teşekkürler!


1
2 karakter kaydetmek için
çizgi

1
İle 4 bayt daha kaydedebilirsiniz z=*(int*)x^*(int*)y;.
Arnauld

1
Gcc uzantıları ile 54 bayt:#define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
Nishioka

2
İşaretçiler kullandığınız için, girdilerden birini çıktı olarak kullanmak yasal mı? Eğer öyleyse, yazabilirsiniz (*(int*)x^=*(int*)y).
Neil

1
@ Neil'in önerisi dikkate alındığında 48 bayta ulaşacaktı:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka

9

ARM Thumb Makine Kodu, 6 4 Byte

48 40 70 47

Montajda:

EORS R0, R1; Münhasır Veya ilk iki parametreden, sonucu iade defterinde saklayın
BX LR; Bağlantı Kaydında depolanan değerin dalı (Dönüş adresi)

Standart Arm çağırma kuralına göre, ilk iki parametre R0 ve R1 kayıtlarına geçirilir, sonuçlar R0 olarak döndürülür ve LR dönüş adresini tutar. 32 bit şamandıralı yumuşak şamandıra ABI kullandığınızı varsayarsak, bu işlem 4 baytta istenen işlemi gerçekleştirir.

Cody Gray sayesinde -2 bayt


2
EORS r0, r1Bunun yerine, 2 bayt kaydetmek için kullanmak mümkün müdür ? Bu 48 40, 4 baytınızla karşılaştırıldığında yalnızca 2 baytlık bir talimattır ( ) EOR. Zaten Thumb'i hedefliyorsunuz, bu yüzden görebildiğim kadarıyla bu iyi çalışıyor. Tek fark, durum bayraklarını güncellemesidir, ancak bu durumda bu yan etkiyi umursamazsınız.
Cody Gray

2
Bunun FP değişkenlerini VFP / NEON s0ve değil tamsayı kayıtlarında geçiren yumuşak şamandıra ABI kullandığını belirtmelisiniz s1.
Peter Cordes

6

Python 3 + numpy, 75 59 bayt

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

Çevrimiçi deneyin!

İki numpy float32 dizisini bağımsız değişken olarak alan ve numpy float32 dizisi döndüren lambda'yı tanımlar.

14 bayt tasarruf ettiği için @ShadowRanger'a ve Joel 2 tane daha teşekkürler!

İçe aktarma bırakılabilirse (lambda'mın kendisi herhangi bir temel numpy işlevi yerine numpy nesnelerine yöntem çağırdığı için) 13 bayt daha kaydedebilirim. Ben kod golf standart kurallar bu konuda emin değilim.


Jelly ve Ruby'nin cevaplarından daha kısa. Güzel!
Eric Duminil

İçe aktarmayı tamamen kaldırarak 27 bayt (48 bayta bırakarak) tıraş edebilirsiniz (sadece arayanın sizi numpy.float32yöntemlerini kullanabilmeniz için geçtiğini varsayın ) ve her iki int32kullanımı 'i've float32kullanımı ile değiştirerek 'f'; dtypeparametre gerçek dönüştürülür alır bir dize olabilir dtypesizin için, ve uygun, 'i've 'f'ithalat için fonksiyonun gerekliliğini ortadan kaldırır o dtypes yapmak için yasal yolları vardır numpyhiç onun ad içine şeyler. Code Golf'ün içe numpy
aktarmayı


İthalatın dahil edilmesi gerektiğini düşündüm, ama emin değilim. İpucu için teşekkürler dtypes!
Nick Kennedy

@NickKennedy: import gerekiyorsa Evet, bu sadece 8 bayt (dan ikişer kaydeder int32için 'i', dört float32kadar 'f'), ancak yine de bir şey. İçe aktarma kesinlikle gerekliyse, import numpypaketin from numpy import*adlarını çıkarmak için kullanmadan paketin var olduğunu iddia etmek için değiştirebilirsiniz . Bu, toplamda 61 bayta kadar altı bayt daha alır.
ShadowRanger

6

Jöle + numpy, 89 77 bayt

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

Çevrimiçi deneyin!

Çoğunlukla numpy nesnesine / nesnesinden dönüştürme ihtiyacı ve numpy'nin Jelly tarafından yüklenmediği için ürettiği Python 3 kodundan daha uzun olma konusundaki şüpheli şerefine sahiptir, bu nedenle __import__()yerleşik kullanılmalıdır.

İki şamandırayı argüman olarak liste olarak alan ve şamandırayı döndüren monadik bir bağlantı.

Aşağıdaki Python 3 kodunu değerlendirir:

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

burada xve ygirdi ile değiştirilir.


5

APL (Dyalog Unicode) , 14 bayt SBCS

Tam program. Stdin'den iki IEEE 754 64 bit kayan nokta sayısının (binary64) 1 sütunlu matrisini ister. Stdout'a böyle bir sayı yazdırır.

645DR≠⌿11DR

Çevrimiçi deneyin!

 istem (yüzer olmayan öğelere daralyan sayılar bu işlevle yüzer öğelere zorlanabilir ⊃⊢⎕DR⍨645,⍨⎕DR)

11⎕DR 1-bit Binary (1) D ata R eprestasyonuna dönüştür (2-satır, 64-sütun matris)

≠⌿ dikey XOR azaltma

645⎕DR 64 bit şamandıraya dönüştürmek (5) D ata R ePresentation (tek sayı)



3

Oktav , 59 bayt

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

Çevrimiçi deneyin!

Tipik altta yatan bitleri değiştirmeden MATLAB / Octave döküm yöntemidir. Bu, bitxoryalnızca tamsayılar üzerinde çalıştığı için gereklidir . Açıkça AssumedTypeüçüncü bir argüman olarak belirtebilseniz bile, kayan nokta sayılarını neden uygulamadıklarını bilmiyorum bitxor. Sanırım tek kullanım eğlence programlama.


FP bit kalıplarındaki bitsel şeyler, montaj dilinde işaret biti ile bir şeyler yapmak veya nadiren bir exp()uygulamanın bir parçası olarak üs alanına bir tamsayı doldurmak için yararlıdır . Ancak Octave'ın copysign ve olumsuzlama için zaten fonksiyonları / operatörleri olduğunu varsayıyorum. Ve AND (sabit bir maske ile) kullanmak ve sonra bir değerin işaretini diğerinin işaretine dayanarak koşullu olarak çevirmek için XOR gibi mikro optimizasyonları umursamıyorlar. Asm gerçek bir optimizasyon projesinde (aslında AVX intrinsics ile C) şamandıra XOR kullandım sonra sıfıra karşı cmp önlemek için işaret bit bakarak.
Peter Cordes




2

C, 23 bayt

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

Çevrimiçi deneyin!

Bu biraz değişken olabilir; işaretçileri floats işaretçileri olarak alır int.

Ancak, işe yarıyor (sonuçta bu C'dir).

Bu, değişkene bir işaretçi alıp yerinde değiştirerek kabul edilebilir girdiden yararlanır. (Kullanılabilir) değer döndürülmez.


2

JavaScript (node.js) ,  105  101 bayt

@Neil tarafından önerilen Kısa Düğüm sürümü @ShieruAsakoto
sayesinde 4 bayt daha kaydetti

Girişi alır (x)(y).

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

Çevrimiçi deneyin!


JavaScript (ES6), 115 bayt

Girişi 2 floatlık bir dizi olarak alır.

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

Çevrimiçi deneyin!


Bilginize Düğüm en Bufferbirkaç bayt kaydeder: a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE()).
Neil

@Neil Teşekkürler! (yerine bir işlev kullanarak 2 bayt daha kaydetti map)
Arnauld

1
Damlama newin new Buffer(4)de iirc çalışması gerekir
Shieru Asakoto


1

Lua , 73 bayt

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

Çevrimiçi deneyin!

Bu kod, 4 baytlık imzasız tamsayıları kabul eder ve yapılandırmada kayar tio.run. Bağımsız değişken olarak girdi ile tam program olarak çalıştırın.


1

Yakut , 78 67 bayt

@Grawity sayesinde -11 bayt.

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

Çevrimiçi deneyin!

Girdi iki yüzer dizidir.


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

@grawity: Harika, çok teşekkür ederim! Yine de kod Python'dan daha uzun. : - /
Eric Duminil

1

Java (JDK) , 109 76 bayt

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

Çevrimiçi deneyin!

Java'da golf oynadım ve bayt sayımının bir parçası olarak LHS bildirgesine ihtiyacım olup olmadığından emin değil miyim? DoubleBinaryOperator kullandıysa, LHS daha kısa olurdu, ancak RHS'nin Double.doubleToLongBits ve Double.longBitsToDouble kullanması gerekecektir, bu aslında daha uzun.

Bayt sayımında önemli tasarruflar sağlayan Neil'e teşekkürler!


1
IIRC, bayt sayımının bir parçası olarak atamaya bile ihtiyacınız yoktur, yalnızca çevrimiçi deneyin'e dahil edebileceğiniz herhangi bir test paketinin parçası olarak! başlığı.
Neil

@Neil Teşekkürler! Bu büyük bir fark yapar!
David Conrad

0

Temiz , 36 bayt

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

Çevrimiçi deneyin!

Neyse ki Realve Inttürleri 64 bit platformlarda aynı boyutlarda ...
Maalesef tam bir imza gerekiyor, aksi takdirde grafik bir çubuk kraker ve her şey segfaultlara dönüşüyor.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.