50 votos

¿Es posible simular una función de piso() con aritmética elemental?

Estoy usando un "lenguaje de programación" que sólo permite operaciones básicas: suma, resta, multiplicación y división.

¿Es posible emular una función de piso (es decir, dejar caer los decimales un número) utilizando sólo esos operadores? Sólo estoy interesado en los números positivos

Edición: Aquí está el documentación describiendo lo que es posible (que es sólo aritmética elemental)

21 votos

Muchos lenguajes de programación hacen un suelo automáticamente cuando se dividen dos enteros.

4 votos

No puedes hacer comparaciones en el programa, ¿verdad?

1 votos

Por cierto, otra referencia: w3.org/TR/css3-values/#calc-notation

48voto

Mathematician171 Puntos 2669

Dejemos que $$f_1(x)=x+c_1$$ $$f_2(x)=x\cdot c_2$$ donde $c_1,c_2$ son algunas constantes, y $f_1$ representa la suma y la resta, y $f_2$ representa la multiplicación y la división. Funciones $f_1$ y $f_2$ tienen función inversa, pero $\lfloor{x}\rfloor$ no tiene una función inversa. Por lo tanto, si suponemos que es posible encontrar $\lfloor{x}\rfloor$ de $x$ utilizando $f_1$ y $f_2$ entonces es posible encontrar $x$ de $\lfloor{x}\rfloor$ . Contradicción.

4 votos

Lo que significa es imposible, Supongo. ¡Empezaré a presionar para que haya una función de piso, entonces!

35 votos

Si se admiten tanto números positivos como negativos, un mapa como $x \mapsto x \cdot x$ no es invertible (y tampoco es constante). Así que puede produce mapas que no son invertibles, en ese caso. Su $f_1$ y $f_2$ son funciones de una variable, mientras que las sumas y multiplicaciones son funciones de dos variables.

5 votos

Por supuesto, aunque sólo tengamos números positivos, algunos polinomios siguen sin ser invertibles. Por ejemplo, dejemos que $g(x) = (x \cdot x) + 5 - (4 \cdot x)$ entonces $g(1)=g(3)$ .

45voto

lhf Puntos 83572

La función suelo tiene discontinuidades de salto.

Una función obtenida con la aritmética elemental es una función racional y ésta sólo puede tener discontinuidades polares (o infinitas).

0 votos

Pero las implementaciones aritméticas reales también tienen discontinuidades.

5 votos

@BenVoigt Entonces la especificación es errónea, que habla específicamente de "Suma", "Resta", "Multiplicación", "División". Incluso en presencia de errores de redondeo, la precisión no es especificado .

28voto

gammatester Puntos 7985

Sí es posible, pero depende de la aritmética disponible y del modo de redondeo. Con IEEE-double se puede redondear un doble $x$ al número entero más cercano con esto:

$c=2^{52};$

$x = x + c; \mathrm{round} = x - c$ para $x\ge 0\;$ y

$x = x - c; \mathrm{round} = x + c$ para $x<0.$

Con el redondeo al siguiente entero se puede implementar el suelo.

7 votos

Sólo una advertencia para el OP: la precisión en el CSS (para el que se hace esta pregunta) es teóricamente infinito en cuyo caso esta respuesta no tendría sentido, pero en la práctica se supone que los números tienen "rangos y precisiones razonablemente útiles", que variarán entre las implementaciones, incluso entre diferentes versiones del mismo navegador.

3 votos

Estás en algo como calc(2.9999px + 9007199254740992px - 9007199254740992px) realmente produce 2px en Chrome ( $c=2^{53}$ ¡)! Como dijo @hvd es probable que dependa de la implementación pero puedo hacer algunas pruebas. En el peor de los casos hago que el navegador se bloquee /s

0 votos

Por otro lado, Firefox tiene un tope de $c=2^{24}$ lo que rompe un poco esta solución (cualquier cosa más alta produce 0)

17voto

Brian J Puntos 244

Si puedes utilizar un bucle y variables adicionales, puedes restar una y otra vez hasta quedarte sólo con la parte decimal.

Algo así como:

floor(x):
floor = 0
While x >= 1
    floor += 1
    x -= 1
End While

No es lo mejor, y llevará mucho tiempo para grandes números, pero se podría ajustar.

Tampoco funciona para valores negativos, pero eso se arregla fácilmente.

1 votos

No me di cuenta de que tu "lenguaje de programación" era css. Dudo mucho que esto funcione en css de forma nativa.

0 votos

No en CSS pero por lo demás esta es la solución que funciona para un lenguaje que lo permita. +1

1 votos

Esto va a devolver floor(1) = 0, ¿no?

11voto

mxmissile Puntos 382

Puedes hacer entero división usando aritmética compleja, pero hay una función diferente para cada divisor. Por ejemplo,

$$\left\lfloor \frac{x}{2} \right\rfloor = \frac{x}{2} - \frac{1 - (-1)^x}{4} $$

para $x$ un número entero. Para un número mayor $k$ usarás $k$ a raíz de la unidad.

1 votos

Esta solución requiere la exponenciación, que no está entre las operaciones permitidas.

0 votos

@ChristianSemrau los ops dados no permiten ni matemáticas complejas (exactas, no en coma flotante) ni raíces arbitrarias de la unidad. La respuesta verdadera es o bien 'no' por la razón dada en la respuesta superior, o bien 'sí' porque el dominio es de enteros y la división de enteros ya da el suelo.

0 votos

Efectivamente. Viendo que el lenguaje de programación indentado es CSS, no se permite ninguna de las dos cosas, y la respuesta es no.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X