Điểm nổi XOR


15

Nhiệm vụ của bạn khá đơn giản. Cho hai số float, bitwise xor biểu diễn nhị phân của chúng và xuất ra dưới dạng float.

Ví dụ,

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

Hạn chế / làm rõ:

  • Đầu vào / đầu ra có thể được đưa ra bởi bất kỳ phương pháp thuận tiện .
  • Chương trình có thể là một chương trình đầy đủ hoặc chỉ là một chức năng; hoặc là tốt.
  • Kiểu float có thể là bất kỳ kích thước nào, nhưng kích thước tối thiểu là 2 byte.
  • Sơ hở tiêu chuẩn bị cấm.
  • Mã ngắn nhất sẽ thắng.

2
Danh sách Boolean có được tính là một phương pháp thuận tiện không?
Adám

23
"Đại diện nhị phân" của một float là vô cùng mơ hồ. Bạn sẽ cần xác định đại diện nào bạn đang sử dụng. Có vô số đại diện, bao gồm cả số hữu hạn đã được sử dụng bởi sự sống trên hành tinh này, một số phổ biến hơn các đại diện khác, chẳng hạn như IEEE 754
Kỹ sư đảo ngược

7
Câu hỏi này sẽ thú vị hơn là "xor các giá trị " thay vì "xor các đại diện". Loại thứ hai tất nhiên giống với "xor hai số nguyên 32 bit" trong bất kỳ ngôn ngữ nào thiếu hệ thống loại hoặc thừa nhận loại xảo quyệt, và do đó khá nhàm chán ...
R .. GitHub DỪNG GIÚP ICE

5
Chúng ta có phải xử lý vô cực, subnormals hoặc âm 0, là đầu vào hoặc đầu ra không?
Grimmy

3
@Mark: Không, như đã viết, câu hỏi chỉ là về việc đại diện cho họ, bất kể những đại diện đó là gì. Kết quả phụ thuộc vào định dạng dấu phẩy động nhưng thuật toán luôn là một lệnh xor duy nhất trên biểu diễn, điều này khá nhàm chán.
R .. GitHub DỪNG GIÚP ICE

Câu trả lời:


53

mã máy x86-64, 4 byte

0f 57 c1 c3

Trong lắp ráp:

xorps xmm0, xmm1
ret

Đây là một hàm có thể gọi được, lấy hai số float hoặc nhân đôi làm đối số (trong xmm0xmm1) và trả về số float hoặc double (in xmm0).

Điều đó phù hợp với các quy ước gọi của cả Windows x64 x86-64 SysV ABI, và hoạt động cho phao cũng như nhân đôi. (Chúng được truyền / trả lại trong 4 hoặc 8 byte thanh ghi XMM thấp).


12

C ++ (gcc) , 74 32 byte

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

Hãy thử trực tuyến!

Trước đây tôi chưa chơi golf trong C ++ nên rất biết ơn tất cả những người đã giúp giảm một nửa kích thước của mã! Một macro lấy con trỏ tới hai float làm đối số của nó và sửa đổi cái đầu tiên để trả về kết quả.

Cảm ơn @ 12Me1 vì đã lưu 2 byte và @Arnauld vì đã lưu 4! Cảm ơn @Nishioka vì đã tiết kiệm thêm 14, @Neil thêm 6 và @AZTECCO và @Nishioka thêm 11! Cảm ơn @PeterCordes đã lưu 5 byte!


1
Bạn có thể xóa các ngắt dòng để lưu 2 ký tự và điều này cũng hoạt động trong C
12Me21

1
Bạn có thể lưu thêm 4 byte với z=*(int*)x^*(int*)y;.
Arnauld

1
Với các tiện ích mở rộng gcc, 54 byte:#define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
Nishioka

2
Vì bạn đang sử dụng con trỏ, việc sử dụng một trong các đầu vào làm đầu ra có hợp pháp không? Nếu vậy, bạn có thể viết (*(int*)x^=*(int*)y).
Neil

1
Cân nhắc đề xuất của @ Neil, nó sẽ lên tới 48 byte:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka

9

Mã máy ARM ARM, 6 4 byte

48 40 70 47

Trong lắp ráp:

EORS R0, R1; Độc quyền Hoặc trong hai thông số đầu tiên, lưu trữ kết quả trong thanh ghi trả lại
BX LR; Nhánh tới giá trị được lưu trong Thanh ghi liên kết (Địa chỉ trả về)

Theo quy ước gọi Arm tiêu chuẩn, hai tham số đầu tiên được truyền vào các thanh ghi R0 và R1, kết quả được trả về trong R0 và LR giữ địa chỉ trả về. Giả sử bạn đang sử dụng ABI float mềm với float 32 bit, điều này sẽ thực hiện thao tác mong muốn trong 4 byte.

-2 byte nhờ Cody Gray


2
EORS r0, r1Thay vào đó, có thể sử dụng để tiết kiệm 2 byte không? Đó chỉ là một lệnh 2 byte ( 48 40), so với 4 byte của bạn EOR. Bạn đã nhắm mục tiêu Thumb, vì vậy điều này sẽ hoạt động tốt, theo như tôi có thể thấy. Sự khác biệt duy nhất là nó cập nhật các cờ trạng thái, nhưng bạn không quan tâm đến tác dụng phụ đó trong trường hợp này.
Cody Grey

2
Bạn nên xác định rằng điều này đang sử dụng ABI float mềm, vượt qua các đối số FP trong các thanh ghi số nguyên, không phải VFP / NEON s0s1.
Peter Cordes

6

Python 3 + gọn gàng, 75 59 byte

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

Hãy thử trực tuyến!

Xác định một lambda lấy hai mảng float32 numpy làm đối số của nó và trả về một mảng float32 numpy.

Cảm ơn @ShadowRanger đã lưu 14 byte và Joel thêm 2!

Nếu quá trình nhập có thể bị hủy (vì chính lambda của tôi gọi các phương thức trên các đối tượng numpy chứ không phải bất kỳ hàm numpy cơ sở nào), tôi có thể lưu thêm 13 byte. Tôi không chắc chắn về điều này từ các quy tắc tiêu chuẩn golf mã.


Nó ngắn hơn câu trả lời của Jelly và Ruby. Đẹp!
Eric Duminil

Bạn có thể loại bỏ 27 byte (giảm xuống còn 48 byte) bằng cách xóa hoàn toàn quá trình nhập (chỉ cần giả sử người gọi đã chuyển bạn numpy.float32để bạn có thể sử dụng phương thức của họ) và thay thế cả cách int32sử dụng 'i'float32sử dụng bằng 'f'; các dtypetham số có thể là một chuỗi đó được chuyển đổi sang các thực dtypecho bạn, và thuận tiện, 'i''f'nhiều cách pháp lý để thực hiện những dtypes, mà loại bỏ sự cần thiết cho các chức năng để nhập khẩu numpycông cụ vào không gian tên của nó cả. Không chắc chắn liệu Code Golf có hợp pháp để xóa nhập hay không nhưng vẫn giả sử numpyđầu vào ...
ShadowRanger


Tôi nghĩ rằng nhập khẩu phải được bao gồm, nhưng tôi không chắc chắn. Cảm ơn các tip re các dtypes!
Nick Kennedy

@NickKennedy: Vâng, nếu yêu cầu nhập, nó chỉ lưu 8 byte (hai từ int32đến 'i', bốn từ float32đến 'f'), nhưng đó vẫn là một cái gì đó. Nếu quá trình nhập được yêu cầu nghiêm ngặt, bạn có thể thay đổi nó import numpyđể xác nhận gói tồn tại mà không cần sử dụng from numpy import*để trích xuất tên từ nó. Điều đó sẽ giúp bạn có thêm sáu byte, tổng cộng xuống còn 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

Hãy thử trực tuyến!

Có một vinh dự đáng ngờ là dài hơn mã Python 3 mà nó tạo ra, phần lớn là do nhu cầu chuyển đổi sang / từ đối tượng numpy và thực tế là numpy không được tải bởi Jelly nên __import__()đã sử dụng tích hợp.

Một liên kết đơn âm lấy hai số float làm danh sách làm đối số của nó và trả về một float.

Đánh giá mã Python 3 sau:

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

trong đó xyđược thay thế bằng đầu vào.


5

APL (Dyalog Unicode) , 14 byte SBCS

Chương trình đầy đủ. Nhắc nhở ma trận 1 cột của hai số dấu phẩy động 64 bit 64 bit (binary64) từ stdin. In một số như vậy vào thiết bị xuất chuẩn.

645DR≠⌿11DR

Hãy thử trực tuyến!

 dấu nhắc (số bị sập thành không nổi có thể được buộc thành phao với chức năng ⊃⊢⎕DR⍨645,⍨⎕DR)

11⎕DR chuyển đổi thành nhị phân 1 bit (1) D ata R epresentation (ma trận 2 hàng, 64 cột)

≠⌿ giảm XOR dọc

645⎕DR chuyển đổi thành float 64-bit (5) D ata R epresentation (số đơn)


4

VAX BASIC (sau này là VMS BASIC, sau đó là Compaq Basic) , 11 byte

H = F XOR G

Có vẻ hơi ngớ ngẩn với tôi, rõ ràng, các ngôn ngữ cũ sẽ làm tốt hơn bởi vì họ không lo lắng nhiều về các vấn đề gõ mạnh.


1
Chào mừng đến với trang web và câu trả lời đầu tiên tốt đẹp! Tôi đã chỉnh sửa những gì dường như là một tiêu đề không liên quan, nhưng nếu không cảm thấy thoải mái để chỉnh sửa lại, cùng với bất kỳ thông tin đi kèm nào
caird coinheringaahing

3

Octave , 59 byte

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

Hãy thử trực tuyến!

Typecast là cách truyền MATLAB / Octave mà không thay đổi các bit cơ bản. Điều này là bắt buộc vì bitxorchỉ hoạt động trên số nguyên. Không biết tại sao họ không bao giờ thực hiện các số dấu phẩy động, mặc dù bạn có thể chỉ định rõ ràng AssumedTypelà đối số thứ ba bitxor. Tôi đoán việc sử dụng duy nhất là lập trình giải trí.


Công cụ bitwise trên các mẫu bit FP rất hữu ích trong ngôn ngữ lắp ráp để thực hiện mọi việc với bit dấu hoặc hiếm khi đưa số nguyên vào trường số mũ như một phần của exp()việc triển khai. Nhưng tôi cho rằng Octave đã có chức năng / toán tử cho copysign và phủ định. Và họ không quan tâm đến việc tối ưu hóa vi mô như sử dụng AND (với mặt nạ không đổi) sau đó XOR để lật điều kiện một dấu hiệu của một giá trị dựa trên dấu hiệu của một giá trị khác. Trong một dự án tối ưu hóa thực sự trong asm (thực tế là C với nội tại AVX) tôi đã sử dụng XOR của float sau đó nhìn vào bit dấu để tránh cmp so với zero.
Peter Cordes




2

C, 23 byte

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

Hãy thử trực tuyến!

Điều này có thể là một chút shifty; nó lấy con trỏ để floatlàm con trỏint s.

Tuy nhiên, nó hoạt động (đây là C sau tất cả).

Điều này tận dụng lợi thế của đầu vào chấp nhận được bằng cách lấy một con trỏ tới biến và sửa đổi nó tại chỗ. Không có giá trị (có thể sử dụng) được trả lại.


2

JavaScript (Node.js) ,  105  101 byte

Phiên bản Node ngắn hơn được đề xuất bởi @Neil
Đã lưu thêm 4 byte nhờ @ShieruAsakoto

Đưa đầu vào là (x)(y).

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

Hãy thử trực tuyến!


JavaScript (ES6), 115 byte

Lấy đầu vào là một mảng gồm 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))

Hãy thử trực tuyến!


Node của FYI Buffertiết kiệm một vài byte : a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE()).
Neil

@Neil Cảm ơn! (đã lưu thêm 2 byte bằng cách sử dụng một hàm thay vì map)
Arnauld

1
Thả newvào new Buffer(4)cũng nên hoạt động iirc
Shieru Asakoto

1

Wolfram Mathicala , 50 byte

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

Mặc dù tôi cực kỳ nghi ngờ rằng điều này có thể được đánh gôn nhiều hơn, hai đối số bổ sung trong RealDigitschức năng dường như là cần thiết để có được kết quả chính xác.

Hãy thử trực tuyến!


1

Lua , 73 byte

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

Hãy thử trực tuyến!

Mã này giả sử số nguyên không dấu 4 byte và số float được cấu hình trên tio.run. Chạy như chương trình đầy đủ với đầu vào là đối số.


1

Ruby , 78 67 byte

-11 byte nhờ @grawity.

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

Hãy thử trực tuyến!

Đầu vào là một mảng gồm hai phao.


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

@grawity: Tuyệt vời, cảm ơn bạn rất nhiều! Mã vẫn còn dài hơn trong Python. : - /
Eric Duminil

1

Java (JDK) , 109 76 byte

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

Hãy thử trực tuyến!

Đã được một thời gian kể từ khi tôi chơi golf ở Java và tôi không chắc mình có cần khai báo trên LHS như một phần của số byte không? Nếu nó sử dụng DoubleBinaryOperator, LHS sẽ ngắn hơn, nhưng RHS sẽ phải sử dụng Double.doubleToLongBits và Double.longBitsToDouble, vì vậy thực sự lâu hơn.

Cảm ơn Neil vì đã tiết kiệm đáng kể số byte!


1
IIRC bạn thậm chí không cần gán như một phần của số byte, chỉ là một phần của bất kỳ bộ kiểm tra nào bạn có thể đưa vào Thử trực tuyến! tiêu đề.
Neil

@Neil Cảm ơn bạn! Điều đó làm cho một sự khác biệt lớn!
David Conrad

0

Sạch , 36 byte

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

Hãy thử trực tuyến!

Rất may RealInt loại và kích thước có cùng kích thước trên nền tảng 64 bit ...
Thật không may yêu cầu một chữ ký hoàn chỉnh nếu không đồ thị biến thành bánh quy cây và mọi thứ tách biệt.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.