Плаваюча точка 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.

645DR≠⌿11DR

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

 підказка (числа, що згортаються на неплавкові, можуть бути змушені в плавати за допомогою функції ⊃⊢⎕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.