Плаваюча точка XOR


15

Ваше завдання досить просте. Давши два поплавця, порозрядно 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

Обмеження / уточнення:

  • Введення / виведення можна надати будь-яким зручним способом .
  • Програма може бути повноцінною програмою або просто функцією; або добре.
  • Тип поплавця може бути будь-якого розміру, але мінімальний розмір - 2 байти.
  • Стандартні лазівки заборонені.
  • Найкоротший код виграє.

2
Чи вважається булевий список зручним методом?
— Адам

23
"двійкове представлення" поплавця є вкрай неоднозначним. Вам потрібно буде визначити, яке представлення ви використовуєте. Існує нескінченна кількість уявлень, у тому числі кінцеве число, яке вже використовує життя на цій планеті, деякі популярніші за інші, наприклад IEEE 754
— інженер, що

7
Це питання було б цікавіше як "xor значення ", а не "xor уявлення". Останнє, звичайно, ідентичне "xor два 32-бітні цілі числа" будь-якою мовою, у якій відсутня система типу або допускає покарання типу, і, таким чином, досить нудно ...
— R .. GitHub STOP HELPING ICE

5
Чи маємо ми обробляти нескінченність, субнормали або мінус 0 як вхід чи вихід?
— Grimmy

3
@ Марк: Ні, як написано, питання полягає лише у формуванні своїх уявлень, якими б вони не були. Результат залежить від формату плаваючої точки, але алгоритм - це завжди одна інструкція xor про подання, що є досить нудним.
— R .. GitHub СТОП ДОПОМОГА

Відповіді:


53

машинний код x86-64, 4 байти

0f 57 c1 c3

У зборі:

xorps xmm0, xmm1
ret

Це функція, що викликається, яка приймає два поплавці чи подвійні як аргументи (в xmm0і xmm1) і повертає плавучий чи подвійний (в xmm0).

Це відповідає умовам викликів як Windows x64, так і x86-64 SysV ABI, і працює як для плаваючих, так і для парних. (Вони передаються / повертаються в низьких 4 або 8 байтах регістрів XMM).


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
Ви можете видалити
— рядкові перерви,

1
Ви можете зберегти ще 4 байти за допомогою z=*(int*)x^*(int*)y;.
— Арнольд

1
З розширеннями GCC, 54 байт:#define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
— Нісіока

2
Оскільки ви використовуєте покажчики, чи законно використовувати один із входів як вихід? Якщо так, ви можете написати (*(int*)x^=*(int*)y).
— Ніл

1
Беручи до уваги @ пропозицію Нілу було б отримати до 48 байт:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
— Нісіока

9

Код машини ARM великого пальця, 6 4 байти

48 40 70 47

У зборі:

EORS R0, R1; Виключний або з перших двох парам, зберігайте результат у регістрі повернення
BX LR; Відгалуження до значення, збереженого в Реєстрі посилань (Повернення адреси)

Відповідно до стандартного режиму виклику Arm, перші два параметри передаються в регістри R0 і R1, результати повертаються в R0, і LR містить зворотну адресу. Якщо припустити, що ви використовуєте м'який поплавок ABI з 32-бітовими поплавцями, це виконає бажану операцію в 4 байти.

-2 байти завдяки Коді Грей


2
Чи можна було б використати EORS r0, r1замість цього, щоб зберегти 2 байти? Це лише 2-байтна інструкція ( 48 40), порівняно з вашою 4-байтною EOR. Ви вже орієнтуєтеся на великий палець, тому, наскільки я бачу, це має добре працювати. Єдина відмінність - це оновлення прапорів статусу, але вас не хвилює цей побічний ефект у цьому випадку.
— Коді Грей

2
Вам слід вказати, що для цього використовується програмний ABI з плавким поплавком, який передає аргументи FP в цілочисельні регістри, а не VFP / NEON s0і s1.
— Пітер Кордес

6

Python 3 + numpy, 75 59 байт

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

Спробуйте в Інтернеті!

Визначає лямбда, який приймає два масиви float32 numpy як свої аргументи і повертає nummy масив float32.

Дякуємо @ShadowRanger за збереження 14 байт, а Джоелю ще 2!

Якщо імпорт можна відмовити (оскільки мій лямбда сам називає методи на numpy об'єктах, а не на будь-яких базових функціях numpy), я міг би зберегти ще 13 байт. Я не впевнений у цьому від стандартних правил коду для гольфу.


Це коротше, ніж відповіді Джеллі та Рубі. Приємно!
— Ерік Дюмініл

Ви можете поголити 27 байт (опустивши його до 48 байт), видаливши імпорт цілком (просто припустіть, що абонент передав вас numpy.float32, щоб ви могли використовувати їх методи) та замінивши і int32використання, 'i'і float32використання 'f'; dtypeпараметр може бути рядком , яка перетворюється в реальному dtypeдля вас, і зручно, 'i'і 'f'законні способи , щоб зробити цей dtypes, що усуває необхідність в функцію для імпорту numpyматеріалу в його простір імен взагалі. Не впевнений, чи законно видаляти імпорт у Code Golf, але все ж припускають numpyвведення ...
— ShadowRanger


Я думав, що імпорт повинен бути включений, але я не впевнений. Дякуємо за підказки про типи!
— Нік Кеннеді

@NickKennedy: Так, якщо потрібно імпорт, вона зберігає тільки 8 байт ( по два від int32до 'i', чотири з float32до 'f'), але це ще що - то. Якщо імпорт суворо необхідний, ви можете просто змінити його import numpyна затвердження наявного пакету, не використовуючи from numpy import*для цього вилучення імен. Це дозволить отримати ще шість байтів, до 61 байт.
— ShadowRanger

6

Желе + нуме, 89 77 байт

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

Спробуйте в Інтернеті!

Має сумнівну честь бути довше, ніж код Python 3, який він відтворює, багато в чому через необхідність перетворення в / з numpy objecte та того, що numpy не завантажується Jelly, тому __import__()вбудований модуль повинен використовуватися.

Монадична посилання, яка бере два плавці як список як аргумент і повертає поплавок.

Оцінює наступний код 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-стовпецьку матрицю з двох 64-бітних чисел з плаваючою комою IEEE 754 (binary64) від stdin. Друкує одне таке число для stdout.

645⎕DR≠⌿11⎕DR⎕

Спробуйте в Інтернеті!

⎕ підказка (числа, що згортаються на неплавкові, можуть бути змушені в плавати за допомогою функції ⊃⊢⎕DR⍨645,⍨⎕DR)

11⎕DR перетворити на 1-бітне двійкове (1) представлення D ata R (2-рядна, 64-стовпчаста матриця)

≠⌿ вертикальне зменшення XOR

645⎕DR перетворити на 64-розрядний флоат (5) Представлення D ata R (єдине число)


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 / Octave без зміни базових бітів. Це потрібно, оскільки bitxorпрацює лише на цілі числа. Поняття не має, чому вони ніколи не реалізували числа з плаваючою комою, хоча ви можете чітко вказати AssumedTypeяк третій аргумент bitxor. Я думаю, єдине використання - це рекреаційне програмування.


Бітові матеріали на бітових шаблонах FP корисні в мові складання, щоб робити речі з бітом знаків, або рідко вводити ціле число в поле експоненту як частину exp()реалізації. Але я припускаю, що в Octave вже є функції / оператори для копіювання та заперечення. І вони не переймаються мікро-оптимізаціями, такими як використання AND (з постійною маскою), тоді XOR умовно перевертає знак одного значення на основі знаку іншого. У реальному проекті оптимізації в ASM (власне, C з AVX-внутрішніми характеристиками) я використав XOR floats, тоді дивлячись на бітовий знак, щоб уникнути cmp проти нуля.
— Пітер Кордес

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 Дякую! (збережено ще 2 байти за допомогою функції замість map)
— Арнольд

1
Кинувши newін new Buffer(4)повинен також працювати IIRC
— Shieru Asakoto



1

Рубі , 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")
— користувач1686,

@grawity: Дивовижний, дуже дякую! Код все ж довший, ніж у Python. : - /
— Ерік Думініл

1

Java (JDK) , 109 76 байт

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

Спробуйте в Інтернеті!

Пройшов час, коли я займався гольфом на Яві, і я не впевнений, чи потрібно мені декларацію про LHS як частину підрахунку байтів? Якщо він використовував DoubleBinaryOperator, LHS був би коротшим, але RHS повинен був би використовувати Double.doubleToLongBits і Double.longBitsToDouble, тож це насправді довше.

Дякуємо Нілу за значну економію на кількості байтів!


1
IIRC, вам навіть не потрібно призначення, як частина підрахунку байтів, лише як частина будь-якого тестового набору, який ви можете включити у свій Спробуйте в Інтернеті! заголовок.
— Ніл

@Neil Дякую! Це має велике значення!
— Девід Конрад

0

Чисто , 36 байт

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

Спробуйте в Інтернеті!

На щастя, Realі Intтипи однакових розмірів на 64-розрядних платформах ...
На жаль, потрібна повна підпис, інакше графік перетворюється на кренделі і все налагоджено.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.