Punto flotante XOR

15

Tu tarea es bastante simple. Dados dos flotantes, bit a bit o la representación binaria de ellos, y generarlo como flotante.

Por ejemplo,

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

Restricciones / aclaraciones:

  • La entrada / salida se puede dar por cualquier método conveniente .
  • El programa puede ser un programa completo o simplemente una función; Cualquiera esta bien.
  • El tipo flotante puede ser de cualquier tamaño, pero el tamaño mínimo es de 2 bytes.
  • Las lagunas estándar están prohibidas.
  • El código más corto gana.
virchau13
fuente
2
¿La lista booleana cuenta como un método conveniente?
Adám
23
La "representación binaria" de un flotador es extremadamente ambigua. Tendrá que definir qué representación está utilizando. Hay un número infinito de representaciones, incluido el número finito ya utilizado por la vida en este planeta, algunas más populares que otras, como IEEE 754
Ingeniero invertido
77
Esta pregunta sería más interesante como "xor los valores " en lugar de "xor las representaciones". Este último es, por supuesto, idéntico al "xor dos enteros de 32 bits" en cualquier idioma que carece de un sistema de tipo o admite tipo de juegos de palabras, y por lo tanto es bastante aburrido ...
R .. GitHub dejar de ayudar a ICE
55
¿Tenemos que manejar infinito, subnormal o 0 negativo, como entrada o salida?
Grimmy
3
@ Mark: No, tal como está escrita, la pregunta es solo acerca de sus representaciones, cualesquiera que sean esas representaciones. El resultado depende del formato de coma flotante, pero el algoritmo siempre es una sola instrucción xor en la representación, lo cual es bastante aburrido.
R .. GitHub DEJA DE AYUDAR A HIELO

Respuestas:

53

Código de máquina x86-64, 4 bytes

0f 57 c1 c3

En asamblea:

xorps xmm0, xmm1
ret

Esta es una función invocable que toma dos flotantes o dobles como argumentos (en xmm0y xmm1) y devuelve un flotante o doble (en xmm0).

Eso coincide con las convenciones de llamadas de Windows x64 y x86-64 SysV ABI, y funciona tanto para flotantes como para dobles. (Se pasan / devuelven en los 4 u 8 bytes bajos de los registros XMM).

harold
fuente
12

C ++ (gcc) , 74 32 bytes

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

Pruébalo en línea!

No he jugado golf previamente en C ++, ¡así que estoy agradecido con todos los que ayudaron a reducir a la mitad el tamaño del código! Una macro que toma punteros a dos flotantes como argumentos y modifica el primero para devolver el resultado.

¡Gracias a @ 12Me1 por guardar 2 bytes y a @Arnauld por guardar 4! ¡Gracias a @Nishioka por salvar otros 14, @Neil otros 6 y @AZTECCO y @Nishioka otros 11! ¡Gracias a @PeterCordes por guardar 5 bytes!

Nick Kennedy
fuente
1
Puede eliminar los saltos de línea para guardar 2 caracteres, y esto también funciona en C
12Me21 el
1
Puede guardar 4 bytes más con z=*(int*)x^*(int*)y;.
Arnauld
1
Con extensiones gcc, 54 bytes:#define f(x,y)({int z=*(int*)x^*(int*)y;*(float*)&z;})
Nishioka
2
Dado que está utilizando punteros, ¿es legal usar una de las entradas como salida? Si es así, podrías escribir (*(int*)x^=*(int*)y).
Neil
1
Teniendo en cuenta la sugerencia de @ Neil, llegaría a 48 bytes:#define f(x,y)({*(int*)x^=*(int*)y;*(float*)x;})
Nishioka,
9

ARM Thumb Machine Code, 6 4 bytes

48 40 70 47

En asamblea:

EORS R0, R1; Exclusivo O de los dos primeros parámetros, el resultado de la tienda en el registro de devolución
BX LR; Se bifurca al valor almacenado en el Registro de enlaces (Dirección de devolución)

Según la convención de llamadas de armado estándar, los dos primeros parámetros se pasan en los registros R0 y R1, los resultados se devuelven en R0 y LR contiene la dirección de retorno. Suponiendo que está utilizando el ABI de flotador suave con flotadores de 32 bits, realizará la operación deseada en 4 bytes.

-2 bytes gracias a Cody Gray

Sir_Lagsalot
fuente
2
¿Sería posible usar EORS r0, r1en su lugar, para ahorrar 2 bytes? Eso es solo una instrucción de 2 bytes ( 48 40), en comparación con su 4 bytes EOR. Ya estás apuntando a Thumb, por lo que debería funcionar bien, por lo que puedo ver. La única diferencia es que actualiza los indicadores de estado, pero en este caso no le importa ese efecto secundario.
Cody Gray
2
Debe especificar que esto está utilizando el ABI de flotación suave que pasa los argumentos FP en registros enteros, no VFP / NEON s0y s1.
Peter Cordes
6

Python 3 + numpy, 75 59 bytes

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

Pruébalo en línea!

Define una lambda que toma dos matrices float32 numpy como argumentos y devuelve una matriz float32 numpy.

¡Gracias a @ShadowRanger por guardar 14 bytes, y a Joel por otros 2!

Si se puede descartar la importación (dado que mi lambda misma llama a métodos en objetos numpy en lugar de cualquier función numpy base), podría guardar otros 13 bytes. No estoy seguro de esto por las reglas estándar del código de golf.

Nick Kennedy
fuente
Es más corto que las respuestas de Jelly y Ruby. ¡Agradable!
Eric Duminil
Puede reducir 27 bytes (reduciéndolo a 48 bytes) eliminando la importación por completo (solo suponga que la persona que llama le pasó numpy.float32para que pueda usar sus métodos) y reemplazando ambos int32usos con 'i'y el float32uso con 'f'; el dtypeparámetro puede ser una cadena que se convierte en real dtypepara usted, y convenientemente, 'i'y 'f'son formas legales de hacer esos tipos, lo que elimina la necesidad de que la función importe numpycosas a su espacio de nombres. No estoy seguro de si es legal Code Golf eliminar la importación pero aún así asumir numpyentradas ...
ShadowRanger
Pensé que las importaciones debían incluirse, pero no estoy seguro. Gracias por el consejo sobre los tipos!
Nick Kennedy el
@NickKennedy: Sí, si se requiere la importación, solo ahorra 8 bytes (dos de cada int32a 'i', cuatro de float32a 'f'), pero eso sigue siendo algo. Si la importación es estrictamente necesaria, puede cambiarla import numpypara afirmar que el paquete existe, sin usar from numpy import*para extraer nombres de él. Eso le daría otros seis bytes, hasta 61 bytes en total.
ShadowRanger
6

Jalea + numpy, 89 77 bytes

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

Pruébalo en línea!

Tiene el dudoso honor de ser más largo que el código de Python 3 que reproduce, en gran parte debido a la necesidad de convertir a / desde objetos numpy y al hecho de que Jelly no carga numpy, por lo __import__()que debe usarse el incorporado.

Un enlace monádico que toma los dos flotantes como una lista como argumento y devuelve un flotante.

Evalúa el siguiente código de Python 3:

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

donde xy yse sustituyen con la entrada.

Nick Kennedy
fuente
5

APL (Dyalog Unicode) , SBCS de 14 bytes

Programa completo Solicita una matriz de 1 columna de dos números de punto flotante IEEE 754 de 64 bits (binario64) de stdin. Imprime uno de esos números en stdout.

645DR≠⌿11DR

Pruébalo en línea!

 prompt (los números que colapsan a no flotantes pueden forzarse a flotar con la función ⊃⊢⎕DR⍨645,⍨⎕DR )

11⎕DR convertir a binario de 1 bit (1) D Representación de ata R (matriz de 2 filas y 64 columnas)

≠⌿ reducción vertical de XOR

645⎕DR convertir a flotante de 64 bits (5) Representación de D ata R (número único)

Adán
fuente
4

VAX BASIC (luego VMS BASIC, luego Compaq Basic) , 11 bytes

H = F XOR G

Me parece un poco tonto, obviamente, a los idiomas más antiguos les irá mejor porque no se preocuparon tanto por los problemas de tipeo fuerte.

RBarryYoung
fuente
1
¡Bienvenido al sitio y buena primera respuesta! He editado lo que parece ser un encabezado extraño, pero si no es así, puede editarlo nuevamente, junto con cualquier información que lo acompañe
caird coinheringaahing
3

Octava , 59 bytes

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

Pruébalo en línea!

Typecast es la forma de conversión de MATLAB / Octave sin cambiar los bits subyacentes. Esto es obligatorio porque bitxorsolo funciona en enteros. No tengo idea de por qué nunca implementaron números de coma flotante, aunque puede especificar explícitamente el AssumedTypecomo tercer argumento bitxor. Supongo que el único uso es la programación recreativa.

Sanchises
fuente
El material bit a bit en los patrones de bit FP es útil en lenguaje ensamblador para hacer cosas con el bit de signo, o rara vez para insertar un número entero en el campo exponente como parte de una exp()implementación. Pero supongo que Octave ya tiene funciones / operadores para copysign y negación. Y no les importan las micro optimizaciones como usar AND (con una máscara constante) y luego XOR para voltear condicionalmente el signo de un valor basado en el signo de otro. En un proyecto de optimización real en asm (en realidad C con intrínsecos AVX), he usado XOR de flotantes y luego he visto el bit de signo para evitar cmp contra cero.
Peter Cordes
2

C, 23 bytes

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

Pruébalo en línea!

Esto podría ser un poco dudoso; toma los punteros a floats como punteros a ints.

Sin embargo, funciona (esto es C después de todo).

Esto aprovecha la entrada aceptable al tomar un puntero a la variable y modificarla en el lugar. No se devuelve ningún valor (utilizable).

SS Anne
fuente
2

JavaScript (Node.js) ,  105  101 bytes

Versión de nodo más corto sugerida por @Neil
Guardado 4 bytes más gracias a @ShieruAsakoto

Toma entrada como (x)(y).

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

Pruébalo en línea!


JavaScript (ES6), 115 bytes

Toma entrada como una matriz de 2 flotadores.

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

Pruébalo en línea!

Arnauld
fuente
FYI Nodo de Bufferahorra unos cuantos bytes: a=>(v=new Buffer(4),[x,y]=a.map(n=>v.writeFloatLE(n)&&v.readInt32LE()),v.writeInt32LE(x^y),v.readFloatLE()).
Neil
@Neil ¡Gracias! (ahorró 2 bytes más usando una función en lugar de map)
Arnauld
1
Dejar caer newen new Buffer(4)también debería funcionar iirc
Shieru Asakoto
1

Wolfram Mathematica , 50 bytes

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

Aunque sospecho firmemente que esto podría ser más complejo, los dos argumentos adicionales en RealDigits función parecen ser necesarios para obtener un resultado correcto.

Pruébalo en línea!

polfosol ఠ_ఠ
fuente
1

Lua , 73 bytes

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

Pruébalo en línea!

Este código supone números enteros y flotantes sin signo de 4 bytes en los que se encuentra la configuración tio.run. Ejecutar como programa completo con entrada como argumentos.

val dice reinstalar a Monica
fuente
1

Rubí , 78 67 bytes

-11 bytes gracias a @grawity.

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

Pruébalo en línea!

La entrada es una matriz de dos flotadores.

Eric Duminil
fuente
x.map{|v|[v].pack(?g).unpack(?N)[0]}x.pack("gg").unpack("NN")
user1686
@grawity: ¡Impresionante, muchas gracias! Sin embargo, el código aún es más largo que en Python. : - /
Eric Duminil
1

Java (JDK) , 109 76 bytes

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

Pruébalo en línea!

¿Ha pasado un tiempo desde que jugué al golf en Java y no estoy seguro de si necesito la declaración en el LHS como parte del recuento de bytes? Si usara DoubleBinaryOperator, el LHS sería más corto, pero el RHS tendría que usar Double.doubleToLongBits y Double.longBitsToDouble, por lo que en realidad es más largo.

¡Gracias a Neil por un ahorro sustancial en el recuento de bytes!

David Conrad
fuente
1
IIRC ni siquiera necesita la asignación como parte del recuento de bytes, solo como parte de cualquier conjunto de pruebas que pueda incluir en su ¡Pruébelo en línea! encabezamiento.
Neil
@Neil ¡Gracias! ¡Eso hace una gran diferencia!
David Conrad
0

Limpiar , 36 bytes

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

Pruébalo en línea!

Afortunadamente, los tipos Realy Intson del mismo tamaño en las plataformas de 64 bits ...
Desafortunadamente, se requiere una firma completa; de lo contrario, el gráfico se convierte en un pretzel y todo se daña.

Οurous
fuente