how - Flotador javascript desde/a bits
script async defer (5)
- JavaScript usa el
double
(IEEE 754) para representar todos los números -
double
consta de los campos [signo, exponente (11 bits), mantisa (52 bits)]. El valor del número se calcula utilizando la fórmula(-1)^sign * (1.mantissa) * 2^(exponent - 1023)
. (1.mantissa
: significa que tomamos bits de mantisa.1.mantissa
1 al principio y marcamos ese valor como número, por ejemplo, si mantisa =101
obtenemos el número1.101 (bin) = 1 + 1/2 + 1/8 (dec) = 1.625 (dec)
. - Podemos obtener el valor de la prueba de bit de
sign
si el número es mayor que cero. Hay un pequeño problema con0
aquí porque eldouble
tiene valores+0
y-0
, pero podemos distinguir estos dos calculando1/value
y verificando si el valor es+Inf
o-Inf
. - Como
1 <= 1.mantissa < 2
podemos obtener un valor de exponente usandoMath.log2
por ejemploMath.floor(Math.log2(666.0)) = 9
por lo que exponente esexponent - 1023 = 9
yexponent = 1032
, que en binario es(1032).toString(2) = "10000001000"
- Después de obtener el exponente, podemos escalar el número a exponente cero sin cambiar la mantisa,
value = value / Math.pow(2, Math.floor(Math.log2(666.0)))
, ahora el valor representa el número(-1)^sign * (1.mantissa)
. Si ignoramos el signo y lo multiplicamos por2^52
obtenemos un valor entero que tiene los mismos bits que 1.mantissa:((666 / Math.pow(2, Math.floor(Math.log2(666)))) * Math.pow(2, 52)).toString(2) = "10100110100000000000000000000000000000000000000000000"
(debemos ignorar el encabezado 1). - Después de un poco de cuerda, obtendrás lo que quieras.
Esto es solo una prueba de concepto, no discutimos números desnormalizados o valores especiales como NaN, pero creo que también puede ampliarse para dar cuenta de estos casos.
Las respuestas de @bensiu están bien, pero si se encuentra usando algún intérprete JS antiguo, puede usar este enfoque.
Estoy intentando realizar algo que es simple para el cerebro en cualquier otro idioma pero no en javascript: saque los bits de la flotación (y viceversa).
En C / C ++ sería algo así como
float a = 3.1415; int b = *((int*)&a);
y viceversa
int a = 1000; float b = *((float*)&a);
En C # puede usar BitConverter ... floatBits o algo parecido en Java ... Incluso en VB6 por el amor de Dios, puede crear un float32 en un int32. ¿Cómo diablos puedo traducir entre y int y un flotador en javascript?
Ciertamente no obtienes nada de bajo nivel como ese en JavaScript. Sería extremadamente peligroso permitir la refundición y el puntero en un lenguaje que debe ser seguro para que lo utilicen los sitios web de atacantes potenciales que no sean de confianza.
Si desea obtener una representación IEEE754 de 32 bits de un valor de precisión simple en un Número (lo que recuerda tampoco es un int; el único tipo de número que obtiene en JavaScript es el double
), tendrá que hacerlo usted mismo a través del violín. El signo, el exponente y la mantisa se unen. Hay código de ejemplo here .
Como han dicho otros carteles, JavaScript está mal escrito, por lo que no hay diferenciación en los tipos de datos de flotar a int o viceversa.
Sin embargo, lo que estás buscando es
flotar a int:
Math.floor( 3.9 ); // result: 3 (truncate everything past .) or
Math.round( 3.9 ); // result: 4 (round to nearest whole number)
Dependiendo de lo que quieras En C / C ++, esencialmente estaría usando Math.floor
para convertir a entero desde float.
int para flotar
var a = 10;
a.toFixed( 3 ); // result: 10.000
function DoubleToIEEE(f)
{
var buf = new ArrayBuffer(8);
(new Float64Array(buf))[0] = f;
return [ (new Uint32Array(buf))[0] ,(new Uint32Array(buf))[1] ];
}
function FloatToIEEE(f)
{
var buf = new ArrayBuffer(4);
(new Float32Array(buf))[0] = f;
return (new Uint32Array(buf))[0];
}
Desafortunadamente, esto no funciona con dobles y en navegadores antiguos.