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

Ограничения / разъяснение:

  • Ввод / вывод может быть дан любым удобным способом .
  • Программа может быть полной программой или просто функцией; либо в порядке.
  • Тип float может быть любого размера, но минимальный размер составляет 2 байта.
  • Стандартные лазейки запрещены.
  • Самый короткий код выигрывает.
virchau13
источник
2
Считает ли логический список удобным методом?
Адам
23
«двоичное представление» числа с плавающей точкой крайне неоднозначно. Вам нужно будет определить, какое представление вы используете. Существует бесконечное число представлений, включая конечное число, уже используемое жизнью на этой планете, некоторые из них более популярны, чем другие, такие как IEEE 754
Reversed Engineer
7
Этот вопрос был бы более интересен как «xor значения », а не «xor представления». Последнее, конечно, идентично «xor два 32-битных целых числа» в любом языке, в котором отсутствует система типов или допускается типирование, и, таким образом, это довольно скучно ...
R .. GitHub STOP HELPING ICE
5
Должны ли мы обрабатывать бесконечность, субнормалы или отрицательный 0 как вход или выход?
Grimmy
3
@Mark: Нет, как написано, вопрос заключается только в том, чтобы изменить их представления, какими бы ни были эти представления. Результат зависит от формата с плавающей запятой, но алгоритм всегда представляет собой одну инструкцию xor для представления, что довольно скучно.
R .. GitHub ОСТАНОВИТЬ, ЧТОБЫ ПОМОЧЬ ЛЬДУ

Ответы:

53

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

0f 57 c1 c3

В сборе:

xorps xmm0, xmm1
ret

Это вызываемая функция, которая принимает два числа с плавающей запятой или удваивается в качестве аргументов (in xmm0и xmm1) и возвращает число с плавающей запятой или double (in 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
Принимая во внимание предложение @ Neil, он получит 48 байтов:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka
9

Машинный код большого пальца ARM, 6 4 байта

48 40 70 47

В сборе:

EORS R0, R1; Исключительно Или из первых двух параметров сохраните результат в регистре возврата
BX LR; Переход к значению, хранящемуся в регистре ссылок (обратный адрес)

Согласно стандартному соглашению о вызове Arm, первые два параметра передаются в регистры R0 и R1, результаты возвращаются в R0, а LR содержит адрес возврата. Предполагая, что вы используете программный интерфейс с плавающей запятой с 32-разрядными числами с плавающей запятой, эта операция будет выполняться в 4 байта.

-2 байта благодаря Коди Грей

Sir_Lagsalot
источник
2
Можно ли использовать EORS r0, r1вместо этого, чтобы сохранить 2 байта? Это всего лишь 2-байтовая инструкция ( 48 40) по сравнению с 4-байтовой EOR. Вы уже нацеливаетесь на Thumb, так что, насколько я вижу, это должно работать нормально. Разница лишь в том, что он обновляет флаги состояния, но в этом случае вам не нужен этот побочный эффект.
Коди Грей
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 и возвращает массив с массивом float32.

Спасибо @ShadowRanger за сохранение 14 байтов, а Джоэлю еще 2!

Если импорт может быть отброшен (так как моя лямбда сама вызывает методы для numpy объектов, а не для любых базовых numpy функций), я мог бы сохранить еще 13 байтов. Я не уверен в этом из кодекса правил игры в гольф.

Ник Кеннеди
источник
Это короче, чем ответы Jelly и Ruby. Ницца!
Эрик
Вы можете сбрить 27 байтов (сбросив их до 48 байтов), полностью удалив импорт (просто предположите, что вызывающий абонент передал вам numpy.float32s, чтобы вы могли использовать их методы) и заменив оба int32использования на, 'i'а float32использование на 'f'; dtypeпараметр может быть строкой , которая преобразуется в реальном dtypeдля вас, и удобно, 'i'и 'f'законные способы , чтобы сделать этот dtypes, что устраняет необходимость в функцию для импорта numpyматериала в его пространство имен вообще. Не уверен, законно ли Code Golf удалить импорт, но все же предполагается numpy
ввод
Я думал, что импорт должен быть включен, но я не уверен. Спасибо за отзыв о dtypes!
Ник Кеннеди
@NickKennedy: Да, если требуется импорт, он экономит только 8 байтов (по два от int32до 'i', по четыре от float32до 'f'), но это все еще что-то. Если импорт строго необходим, вы можете просто изменить его, import numpyчтобы утверждать, что пакет существует, без использования from numpy import*для извлечения имен из него. Это даст вам еще шесть байтов, всего до 61 байта.
ShadowRanger
6

Желе + NumPy, 89 77 байт

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

Попробуйте онлайн!

Имеет сомнительную честь быть длиннее, чем код Python 3, который он воспроизводит, в основном из-за необходимости конвертировать в / из numpy objecte и того факта, что jelly не загружается 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. Выводит один такой номер на стандартный вывод.

645DR≠⌿11DR

Попробуйте онлайн!

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

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

≠⌿ вертикальное уменьшение XOR

645⎕DR обращенный к 64-битной плавающей точкой (5) Д ата Р epresentation (единственное число)

Адам
источник
4

VAX BASIC (позже VMS BASIC, затем Compaq Basic) , 11 байт

H = F XOR G

Мне кажется немного глупым, очевидно, что старые языки будут лучше, потому что они не слишком беспокоятся о проблемах со строгой типизацией.

RBarryYoung
источник
1
Добро пожаловать на сайт и приятного первого ответа! Я отредактировал то, что кажется посторонним заголовком, но если не стесняйтесь, отредактируйте его обратно вместе с любой сопроводительной информацией
caird coinheringaahing
3

Октава , 59 байт

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

Попробуйте онлайн!

Typecast - это способ приведения MATLAB / Octave без изменения базовых битов. Это необходимо, потому что bitxorработает только на целых числах. Не знаю, почему они никогда не реализовывали числа с плавающей запятой, даже если вы можете явно указать в AssumedTypeкачестве третьего аргумента bitxor. Я предполагаю, что единственное использование - рекреационное программирование.

Sanchises
источник
Битовые данные в битовых шаблонах FP полезны на ассемблере для выполнения операций со знаковым битом или редко для вставки целого числа в поле экспоненты как часть exp()реализации. Но я предполагаю, что у Octave уже есть функции / операторы для copysign и отрицания. И они не заботятся о микрооптимизациях, таких как использование AND (с постоянной маской) и XOR, чтобы условно перевернуть знак одного значения на основе знака другого. В реальном проекте оптимизации в asm (на самом деле C с внутренними AVX) я использовал XOR с плавающей точкой, а затем смотрел на знаковый бит, чтобы избежать cmp против нуля.
Питер Кордес
2

C # (интерактивный компилятор Visual C #) , 92 байта

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

Попробуйте онлайн!

Воплощение невежества
источник
1
Вы можете использовать небезопасный код для этого, хотя я не уверен, должно ли ключевое слово «unsafe» влиять на число пользователей.
минус семь
2

C, 23 байта

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

Попробуйте онлайн!

Это может быть немного изменчиво; он принимает указатели на floats как указатели на ints.

Тем не менее, это работает (это C в конце концов).

Это использует преимущества приемлемого ввода, беря указатель на переменную и модифицируя ее на месте. Нет (полезное) значение не возвращается.

СС Энн
источник
2

JavaScript (Node.js) ,  105  101 байт

@Neil предложила более короткую версию узла. С помощью @ShieruAsakoto удалось сохранить еще
4 байта

Принимает вход как (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))

Попробуйте онлайн!

Arnauld
источник
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)
Arnauld
1
Бросив newин new Buffer(4)должен также работать IIRC
Shieru Asakoto
1

Wolfram Mathematica , 50 байтов

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

Хотя я сильно подозреваю, что это может быть больше в гольфе, два дополнительных аргумента в RealDigits функции кажутся необходимыми для получения правильного результата.

Попробуйте онлайн!

Полфосол ఠ_ఠ
источник
1

Луа , 73 байта

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

Попробуйте онлайн!

Этот код предполагает 4-байтовые целые числа без знака и число с плавающей запятой, на котором выполняется конфигурация tio.run. Запустите как полную программу с вводом в качестве аргументов.

Валь говорит восстановить Монику
источник
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")
user1686
@ Grawity: Круто, большое спасибо! Код все еще длиннее, чем в Python. : - /
Эрик
1

Java (JDK) , 109 76 байт

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

Попробуйте онлайн!

Прошло какое-то время с тех пор, как я играл в гольф на Java, и я не уверен, что мне нужно объявление о LHS как часть количества байтов? Если бы он использовал DoubleBinaryOperator, LHS был бы короче, но RHS должен был бы использовать Double.doubleToLongBits и Double.longBitsToDouble, так что это на самом деле дольше.

Спасибо Нейлу за значительную экономию на счетчике байтов!

Дэвид Конрад
источник
1
IIRC вам даже не нужно задание как часть количества байтов, а только как часть любого набора тестов, который вы можете включить в свой Попробуй онлайн! заголовок.
Нил
@Neil Спасибо! Это имеет большое значение!
Дэвид Конрад,
0

Чисто , 36 байт

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

Попробуйте онлайн!

К счастью, Realи Intтипы одинаковые размеры на 64-битных платформах ...
К сожалению , требует полной подпись иначе графа превращается в кренделя и все , что ошибки сегментации.

Οurous
источник