Floating Point XOR


15

งานของคุณค่อนข้างง่าย ให้สองลอย, bitwise xor แทนไบนารีของพวกเขาและส่งออกที่เป็นลอย

ตัวอย่างเช่น,

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

ข้อ จำกัด / ชี้แจง:

  • เข้า / ส่งออกจะได้รับโดยใด ๆวิธีที่สะดวก
  • โปรแกรมสามารถเป็นโปรแกรมเต็มรูปแบบหรือเพียงแค่ฟังก์ชั่น; อย่างใดอย่างหนึ่งก็ดี
  • ประเภท float สามารถมีขนาดใดก็ได้ แต่ขนาดต่ำสุดคือ 2 ไบต์
  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  • รหัสที่สั้นที่สุดชนะ

2
รายการบูลีนนับเป็นวิธีที่สะดวกหรือไม่
อดัม

23
"การแทนไบนารี" ของโฟลตนั้นไม่ชัดเจนอย่างยิ่ง คุณจะต้องกำหนดตัวแทนที่คุณใช้ มีตัวแทนจำนวนไม่ จำกัด รวมถึงจำนวน จำกัด ที่ใช้โดยชีวิตบนโลกนี้แล้วบางคนก็ได้รับความนิยมมากกว่าคนอื่นเช่น IEEE 754
วิศวกรที่กลับรายการ

7
คำถามนี้น่าสนใจมากขึ้นว่า "xor the values " แทนที่จะเป็น "xor the Representations" หลังเป็นของที่เหมือนกันแน่นอน "xor จำนวนเต็มสองจำนวน 32 บิต" ในภาษาใด ๆ ที่ขาดระบบการพิมพ์หรือยอมรับประเภทเล่นสำนวนและทำให้เป็นที่น่าเบื่อสวย ...
R .. GitHub ช่วยหยุด ICE

5
เราต้องจัดการกับอินฟินิตี้, subnormals หรือลบ 0 เป็นทั้งอินพุตหรือเอาต์พุตหรือไม่?
Grimmy

3
@ Mark: ไม่เป็นคำถามที่เขียนเป็นเพียงเกี่ยวกับการเป็นตัวแทนของพวกเขาหรือสิ่งที่เป็นตัวแทนเหล่านั้น ผลลัพธ์ขึ้นอยู่กับรูปแบบจุดลอยตัว แต่อัลกอริทึมนั้นเป็นคำสั่ง xor เดียวในการเป็นตัวแทนซึ่งน่าเบื่อมาก
. GitHub หยุดช่วยน้ำแข็ง

คำตอบ:


53

รหัสเครื่อง x86-64 ขนาด 4 ไบต์

0f 57 c1 c3

ในการชุมนุม:

xorps xmm0, xmm1
ret

นี่คือฟังก์ชั่น callable ที่ใช้สองลอยหรือคู่เป็นอาร์กิวเมนต์ (ในxmm0และxmm1) และส่งกลับลอยหรือสอง (ในxmm0)

ที่ตรงกับรูปแบบการโทรของทั้ง Windows x64 และ x86-64 SysV ABI และทำงานได้ทั้งแบบลอยและแบบสองเท่า (พวกเขากำลังผ่าน / ส่งกลับในการลงทะเบียน XMM ต่ำ 4 หรือ 8 ไบต์)


12

C ++ (gcc) , 74 32 ไบต์

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

ลองออนไลน์!

ก่อนหน้านี้ฉันไม่ได้เล่นกอล์ฟด้วยภาษา C ++ ดังนั้นฉันรู้สึกขอบคุณทุกคนที่ช่วยลดขนาดรหัสลงครึ่งหนึ่ง! แมโครที่ใช้พอยน์เตอร์ถึงสองลอยตัวเป็นอาร์กิวเมนต์และแก้ไขค่าแรกเพื่อส่งคืนผลลัพธ์

ขอบคุณ @ 12Me1 สำหรับการบันทึก 2 ไบต์และ @Arnauld สำหรับการบันทึก 4! ขอขอบคุณ @Nishioka ที่ช่วยประหยัดอีก 14 คน @Neil อีก 6 คนและ @AZTECCO และ @Nishioka อีก 11 คน! ขอบคุณ @PeterCordes สำหรับการบันทึก 5 ไบต์!


1
คุณสามารถลบ linebreaks เพื่อบันทึก 2 chars และสามารถใช้ได้ใน C
12Me21

1
คุณสามารถบันทึก 4 z=*(int*)x^*(int*)y;ไบต์มากขึ้นด้วย
Arnauld

1
ด้วยส่วนขยาย gcc ขนาด 54 ไบต์:#define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
Nishioka

2
เนื่องจากคุณใช้พอยน์เตอร์การใช้อินพุตใดอินพุตหนึ่งเป็นเอาต์พุตถูกต้องหรือไม่ (*(int*)x^=*(int*)y)ถ้าเป็นเช่นนั้นคุณสามารถเขียน
Neil

1
เมื่อพิจารณาถึงข้อเสนอแนะของ @ Neil มันจะมีขนาดถึง 48 ไบต์:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka

9

รหัสเครื่อง ARM ARM 6 6ไบต์

48 40 70 47

ในการชุมนุม:

Eors R0, R1; เอกสิทธิ์หรือสองพารามิเตอร์แรกเก็บผลลัพธ์ในรีจิสเตอร์กลับ
BX LR; สาขาไปยังค่าที่เก็บไว้ในลิงค์ลงทะเบียน (ที่อยู่ผู้ส่ง)

ภายใต้หลักการเรียก Arm แบบมาตรฐานพารามิเตอร์สองตัวแรกจะถูกส่งผ่านในรีจิสเตอร์ R0 และ R1 ผลลัพธ์จะถูกส่งคืนใน R0 และ LR จะเก็บแอดเดรสที่อยู่ผู้ส่ง สมมติว่าคุณกำลังใช้ soft float ABI ที่มี 32 บิตลอยสิ่งนี้จะทำงานตามที่ต้องการใน 4 ไบต์

-2 ไบต์ต้องขอบคุณ Cody Gray


2
เป็นไปได้ไหมที่จะใช้EORS r0, r1แทนเพื่อประหยัด 2 ไบต์? นั่นเป็นเพียงคำสั่ง 2 ไบต์ ( 48 40) เปรียบเทียบกับ 4 ไบต์ของEORคุณ คุณกำลังกำหนดเป้าหมายเป็น Thumb อยู่แล้วดังนั้นนี่จึงใช้ได้ดีเท่าที่ฉันเห็น ข้อแตกต่างเพียงอย่างเดียวก็คือมันจะอัปเดตสถานะสถานะ แต่คุณไม่สนใจผลข้างเคียงนั้นในกรณีนี้
โคดี้เกรย์

2
คุณควรระบุว่านี่คือการใช้นุ่มลอย ABI ที่ผ่าน args FP ในทะเบียนจำนวนเต็มไม่ VFP / นีออนและs0 s1
Peter Cordes

6

Python 3 + จำนวน, 75 59 ไบต์

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

ลองออนไลน์!

กำหนดแลมบ์ดาซึ่งใช้เวลาสอง numpy float32 อาร์เรย์เป็นอาร์กิวเมนต์และส่งกลับอาร์เรย์ numpy float32

ขอบคุณ @ShadowRanger สำหรับการบันทึก 14 ไบต์และ Joel อีก 2 ตัว!

หากการนำเข้าสามารถลดลงได้ (เนื่องจากแลมบ์ดาของฉันเองเรียกใช้วิธีการกับวัตถุที่เป็นวัตถุมากกว่าฟังก์ชั่นฐาน numpy ใด ๆ ) ฉันสามารถบันทึกได้อีก 13 ไบต์ ฉันไม่แน่ใจในเรื่องนี้จากกฎมาตรฐานของกอล์ฟ


มันสั้นกว่าคำตอบของ Jelly และ Ruby ดี!
Eric Duminil

คุณสามารถโกน 27 ไบต์ (ลดลงเหลือ 48 ไบต์) โดยลบการนำเข้าทั้งหมด (เพียงสมมติว่าผู้โทรผ่านคุณnumpy.float32เพื่อให้คุณสามารถใช้วิธีการของพวกเขา) และแทนที่การint32ใช้ทั้งสองด้วย'i'และการfloat32ใช้งานด้วย'f'; dtypeพารามิเตอร์สามารถเป็นสตริงซึ่งได้รับการแปลงจริงdtypeสำหรับคุณและสะดวก'i'และ'f'มีวิธีการตามกฎหมายเพื่อให้ dtypes เหล่านั้นซึ่งไม่จำเป็นต้องใช้ฟังก์ชั่นที่จะนำเข้าnumpyสิ่งที่เข้ามาใน namespace ที่ทั้งหมด ไม่แน่ใจว่ามันรหัสกอล์ฟตามกฎหมายที่จะเอานำเข้า แต่ก็ยังถือว่าnumpyปัจจัยการผลิต ...
ShadowRanger


ฉันคิดว่าจะต้องรวมการนำเข้า แต่ฉันไม่แน่ใจ ขอบคุณสำหรับเคล็ดลับอีกครั้ง dtypes!
Nick Kennedy

@NickKennedy: ใช่ถ้าจำเป็นต้องนำเข้ามันจะบันทึกได้เพียง 8 ไบต์ (สองตัวต่อจากint32ถึง'i'สี่จากfloat32ถึง'f') แต่ก็ยังมีบางอย่าง หากต้องการนำเข้าอย่างเคร่งครัดคุณสามารถเปลี่ยนเป็นimport numpyยืนยันแพคเกจที่มีอยู่โดยไม่ต้องใช้from numpy import*เพื่อแยกชื่อจากมัน นั่นจะทำให้คุณมีอีกหกไบต์รวมกันได้ถึง 61 ไบต์
ShadowRanger

6

Jelly + numpy, 89 77 ไบต์

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

ลองออนไลน์!

มีเกียรติที่น่าสงสัยในการเป็นเวลานานกว่ารหัส Python 3 ที่มันทำซ้ำส่วนใหญ่เป็นเพราะความต้องการที่จะแปลงเป็น / จากวัตถุ numpy และความจริงที่ว่า numpy ไม่ได้โหลดโดย Jelly ดังนั้นใน__import__()ตัวจึงต้องใช้

ลิงก์ monadic ที่นำทั้งสอง float เป็นรายการเป็นอาร์กิวเมนต์และส่งคืน float

ประเมินรหัส Python 3 ต่อไปนี้:

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

ที่ไหนxและyถูกทดแทนด้วยการป้อนข้อมูล


5

APL (Dyalog Unicode) , 14 ไบต์SBCS

โปรแกรมเต็มรูปแบบ แสดงพร้อมต์สำหรับเมทริกซ์ 1 คอลัมน์ของสองหมายเลข IEEE 754 64- บิตเลขทศนิยม (binary64) จาก stdin พิมพ์หนึ่งหมายเลขดังกล่าวเป็น stdout

645DR≠⌿11DR

ลองออนไลน์!

 พรอมต์ (ตัวเลขที่ยุบไปยังไม่ใช่ลอยตัวสามารถบังคับให้ลอยด้วยฟังก์ชั่น⊃⊢⎕DR⍨645,⍨⎕DR)

11⎕DR แปลงเป็นไบนารีแบบ 1 บิต (1) การแสดงผลD ata R (เมทริกซ์ 2 แถว, 64- คอลัมน์)

≠⌿ การลด XOR ในแนวตั้ง

645⎕DR แปลงเป็นทศนิยม 64 บิต (5) D ata R epresentation (หมายเลขเดียว)


4

VAX BASIC (ภายหลัง VMS BASIC จากนั้น Compaq Basic) 11 ไบต์

H = F XOR G

ดูเหมือนว่าฉันจะโง่เล็กน้อยแน่ ๆ ภาษาที่เก่ากว่าจะทำได้ดีกว่าเพราะพวกเขาไม่ต้องกังวลกับปัญหาการพิมพ์ที่แรงเกินไป


1
ยินดีต้อนรับสู่เว็บไซต์และคำตอบแรกที่ดี! ฉันได้แก้ไขสิ่งที่ดูเหมือนจะเป็นส่วนหัวที่ไม่เกี่ยวข้อง แต่หากไม่สามารถแก้ไขได้กลับมาพร้อมกับข้อมูลเพิ่มเติมใด ๆ
caird coinheringaahing

3

อ็อกเทฟ 59 ไบต์

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

ลองออนไลน์!

Typecast เป็นวิธีการหล่อ MATLAB / ระดับแปดเสียงโดยไม่ต้องเปลี่ยนบิตพื้นฐาน สิ่งนี้จำเป็นเนื่องจากbitxorใช้งานได้กับจำนวนเต็มเท่านั้น คิดว่าทำไมพวกเขาไม่เคยนำมาใช้ตัวเลขทศนิยมแม้ว่าคุณอย่างชัดเจนสามารถระบุไม่มีเป็นอาร์กิวเมนต์ที่สามไปAssumedType bitxorฉันเดาว่าใช้เพียงอย่างเดียวคือการเขียนโปรแกรมเพื่อสันทนาการ


สิ่งบิตบนลวดลายบิต FP มีประโยชน์ในภาษาแอสเซมบลีเพื่อทำสิ่งต่าง ๆ ด้วยเครื่องหมายบิตหรือไม่ค่อยใส่จำนวนเต็มลงในฟิลด์เลขชี้กำลังซึ่งเป็นส่วนหนึ่งของexp()การนำไปใช้ แต่ฉันคิดว่า Octave มีฟังก์ชั่น / โอเปอเรเตอร์สำหรับ copysign และ negation และพวกเขาไม่สนใจเกี่ยวกับการปรับให้เหมาะสมแบบไมโครเช่นการใช้ AND (กับหน้ากากที่มีค่าคงที่) จากนั้น XOR เพื่อพลิกสัญญาณของค่าหนึ่งอย่างมีเงื่อนไขตามสัญลักษณ์ของอีกอันหนึ่ง ในโครงการเพิ่มประสิทธิภาพที่แท้จริงใน asm (จริง ๆ C กับ AVX อินทริน) ฉันได้ใช้ XOR ของลอยแล้วดูที่บิตสัญญาณเพื่อหลีกเลี่ยง cmp กับศูนย์
Peter Cordes

2

C # (Visual C # Interactive Compiler) , 92 ไบต์

x=>BitConverter.Int32BitsToSingle(x.Aggregate(0,(a,b)=>a^BitConverter.SingleToInt32Bits(b)))

ลองออนไลน์!


1
คุณสามารถใช้รหัสที่ไม่ปลอดภัยสำหรับสิ่งนี้ได้ แต่ฉันไม่แน่ใจว่าคำหลัก "ไม่ปลอดภัย" ควรมีผลต่อจำนวนไบต์หรือไม่
ลบเจ็ด



2

C, 23 ไบต์

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

ลองออนไลน์!

นี่อาจเป็นสิ่งที่ไม่ดีนัก มันใช้ตัวชี้ไปยังfloats เป็นตัวชี้ไปยังints

อย่างไรก็ตามมันใช้งานได้ (นี่คือ C หลังจากทั้งหมด)

สิ่งนี้ใช้ประโยชน์จากอินพุตที่ยอมรับได้โดยการใช้ตัวชี้ไปยังตัวแปรและปรับเปลี่ยนให้เข้าที่ ไม่มีการส่งคืนค่า (ใช้งานได้)


2

JavaScript (Node.js) ,  105  101 ไบต์

รุ่นที่สั้นกว่าแนะนำโดย @Neil
บันทึกอีก 4 ไบต์ขอบคุณ @ShieruAsakoto

(x)(y)จะเข้าเป็น

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

ลองออนไลน์!


JavaScript (ES6), 115 ไบต์

รับอินพุตเป็นอาร์เรย์จำนวน 2 ลอย

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

ลองออนไลน์!


FYI โหนดประหยัดไม่กี่ไบต์:Buffer a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE())
Neil

@ Neil ขอบคุณ! (บันทึกอีก 2 ไบต์โดยใช้ฟังก์ชั่นแทนmap)
Arnauld

1
การลดลงของnewในnew Buffer(4)ควรทำงาน iirc
Shieru Asakoto

1

Wolfram Mathematicaขนาด 50 ไบต์

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

แม้ว่าฉันจะสงสัยอย่างยิ่งว่าสิ่งนี้อาจจะตีกอล์ฟได้มากกว่า แต่ข้อโต้แย้งเพิ่มเติมสองประการ RealDigitsฟังก์ชั่นดูเหมือนจะจำเป็นสำหรับการได้รับผลลัพธ์ที่ถูกต้อง

ลองออนไลน์!


1

Lua , 73 ไบต์

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

ลองออนไลน์!

รหัสนี้อนุมาน 4 tio.runไบต์จำนวนเต็มไม่ได้ลงนามและลอยซึ่งเป็นกำหนดค่าบน เรียกใช้เป็นโปรแกรมเต็มรูปแบบด้วยอินพุตเป็นอาร์กิวเมนต์


1

Ruby , 78 67 ไบต์

-11 ไบต์ขอบคุณ @grawity

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

ลองออนไลน์!

อินพุตเป็นอาร์เรย์ของสองลอย


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

@grawity: เยี่ยมมากขอบคุณมาก! ถึงแม้ว่ารหัสจะยาวกว่าใน Python : - /
Eric Duminil

1

Java (JDK) , 109 76 ไบต์

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

ลองออนไลน์!

นานแล้วตั้งแต่ฉันเล่นกอล์ฟใน Java และฉันไม่แน่ใจว่าฉันต้องการประกาศใน LHS เป็นส่วนหนึ่งของการนับไบต์หรือไม่ หากใช้ DoubleBinaryOperator LHS จะสั้นลง แต่ RHS จะต้องใช้ Double.doubleToLongBits และ Double.longBitsToDouble ดังนั้นจึงใช้งานได้นานกว่า

ขอบคุณ Neil สำหรับการประหยัดที่สำคัญในจำนวนไบต์!


1
IIRC คุณไม่จำเป็นต้องมีการมอบหมายให้เป็นส่วนหนึ่งของจำนวนไบต์ แต่เป็นส่วนหนึ่งของชุดทดสอบใด ๆ ที่คุณอาจรวมไว้ในลองใช้งานออนไลน์! หัวข้อ.
Neil

@Neil ขอบคุณ! นั่นทำให้ความแตกต่างใหญ่!
David Conrad

0

ทำความสะอาด , 36 ไบต์

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

ลองออนไลน์!

โชคดีที่ชนิดRealและIntขนาดเท่ากันบนแพลตฟอร์ม 64 บิต ...
น่าเสียดายที่ต้องมีลายเซ็นที่สมบูรณ์มิฉะนั้นกราฟจะกลายเป็นเพรทเซลและทุกอย่าง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.