with parse number funcion cual javascript parseint

javascript - number - ¿Por qué parseInt(''dsff66'', 16) devuelve 13?



parseint php (4)

¿Por qué alguien querría que esta función se comporte de esta manera (devolver un número entero incluso si no es la representación precisa de la cadena pasada)?

Debido a que la mayoría de las veces (de lejos) está trabajando con números de base 10, y en ese caso, JS simplemente puede convertir , no analizar, la cadena a un número. (Edición: Aparentemente no solo base-10; consulte la actualización a continuación).

Dado que JS se escribe dinámicamente, algunas cadenas funcionan bien como números sin ningún trabajo de su parte. Por ejemplo:

"21" / 3; // => 7 "12.4" / 4; // => 3.1

No hay necesidad de parseInt allí, porque "21" y "12.4" son esencialmente números. Sin embargo, si la cadena fuera "12.4xyz" entonces obtendrías NaN al dividir, ya que decididamente no es un número y no se puede convertir o coercer implícitamente a uno.

También puede explícitamente "convertir" una cadena a un número con Number(someString) . Si bien también es compatible con la base 10, devolverá NaN para cadenas no válidas.

Entonces, debido a que JS ya tiene conversión / conversión / coerción de tipo implícita y explícita, el rol de parseInt no es ser otra función de conversión de tipo.

parseInt de parseInt es, en cambio, ser una función de análisis . Una función que hace todo lo posible para darle sentido a su entrada, devolviendo lo que puede. Es para cuando tienes una cadena que no puedes lanzar simplemente porque no es perfectamente numérica. (Y, al igual que la sintaxis básica de JS, es una reminiscencia de C, como la respuesta de apsillers se explica muy bien).

Y como es un analizador, no una función de lanzamiento, tiene la característica adicional de poder manejar otras bases diferentes a 10.

Ahora, puede preguntar por qué no hay una función de conversión estricta que maneje números que no sean de base 10, y se quejaría como quisiera, pero ... oye, simplemente no lo hay. Los diseñadores de JS simplemente decidieron que parseInt sería suficiente, porque, nuevamente, 0x63 por ciento de las veces, estás tratando con la base 10.

Lo más cerca que puedes llegar al "casting" es probablemente algo horrible como:

var hexString = "dsff66"; var number = eval("0x" + hexString); // attempt to interpret as a hexadecimal literal

lo que lanzará un SyntaxError porque 0xdsff66 no es un literal hex válido.

Actualización: como señala Lekensteyn en los comentarios, JS parece lanzar correctamente cadenas hexadecimales prefijadas con 0x también. No sabía esto, pero de hecho esto parece funcionar:

1 * "0xd0ff66"; // => 13696870 1 * "0xdsff66"; // => NaN

lo que lo convierte en la forma más sencilla de convertir una cadena hexadecimal en un número, y obtener NaN si no se puede representar adecuadamente.

El mismo comportamiento se aplica a Number() , por ejemplo, Number("0xd0ff66") devuelve un entero, y Number("0xdsff66") devuelve NaN .

( / actualizar )

Alternativamente, puede verificar la cadena de antemano y devolver NaN si es necesario:

function hexToNumber(string) { if( !/^(0x)?[0-9a-f]+$/i.test(string) ) return Number.NaN; return parseInt(string, 16); }

Hoy me topé con un caso extraño (en mi opinión) en JavaScript. Pasé una cadena no hexadecimal a la función parseInt con la base de 16 y ... obtuve el resultado. Espero que la función lance algún tipo de excepción o al menos devuelva NaN, pero logró analizarla y devolvió un int.

Mi llamada fue:

var parsed = parseInt(''dsff66'', 16); // note the ''s'' in the first argument document.write(parsed);

y el resultado fue: 13 .

Noté que "detiene" el análisis con el primer carácter que no pertenece al sistema de numeración especificado en el segundo argumento, por lo que al llamar a parseInt(''fg'',16) obtendría 15 como resultado.

En mi opinión, debería devolver NaN. ¿Puede alguien explicarme por qué no lo hace? ¿Por qué alguien querría que esta función se comporte de esta manera (devolver un número entero incluso si no es la representación precisa de la cadena pasada)?


En este caso particular, parseInt() interpreta la letra de "A" a "F" como hexadecimal y los analiza en números decimales. Eso significa que d devolverá 13 .

Lo que hace parseInt () hace

  • parseInt("string", radix) interpreta números y letras en la cadena como hexadecimal (depende de la raíz) al número.

  • parseInt() solo analiza el número o la letra como hexadecimal desde el principio de la cadena hasta que el carácter no sea válido como hexadecimal.

  • Si parseInt() no puede encontrar ningún número o letra como hexadecimal al principio de la cadena, parseInt() devolverá NaN .

  • Si el radix no está definido, el radix es 10 .

  • Si la cadena comienza con "0x" , la raíz es 16 .

  • Si el radix define 0 , el radix es 10 .

  • Si la raíz es 1 , parseInt() devuelve NaN.

  • Si la raíz es 2 , parseInt() solo analiza "0" y "1" .

  • Si la raíz es 3 , parseInt () solo analiza "0" , "1" y "2" . Y así.

  • parseInt() parse "0" a 0 si no hay un número lo sigue como resultado y elimina 0 si hay un número lo sigue. por ejemplo, "0" devuelve 0 y "01" devuelve 1.

  • Si la raíz es 11 , parseInt() solo analiza la cadena que comienza con el número desde "0" hasta "9" y / o la letra "A" .

  • Si la raíz es 12 , parseInt solo analiza la cadena que comienza con el número de "0" a "9" y / o la letra "A" y "B" , y así sucesivamente.

  • el radix máximo es 36 , analizará la cadena que comienza con el número de "0" a "9" y / o la letra de "A" a "Z" .

  • Si los caracteres se interpretan como hexadecimales más de uno, cada carácter tendrá un valor diferente, aunque esos caracteres tengan el mismo carácter. por ejemplo, parseInt("AA", 11) la primera "A" tiene un valor diferente con la segunda "A" .

  • Radix diferente devolverá un número diferente aunque las cadenas sean la misma cadena.

Verlo en acción

document.body.innerHTML = "<b>What parseInt() does</b><br>" + "parseInt(''9'') = " + parseInt(''9'') + "<br>" + "parseInt(''0129ABZ'', 0) = " + parseInt(''0129ABZ'', 0) + "<br>" + "parseInt(''0'', 1) = " + parseInt(''0'', 1) + "<br>" + "parseInt(''0'', 2) = " + parseInt(''0'', 2) + "<br>" + "parseInt(''10'', 2) = " + parseInt(''10'', 2) + "<br>" + "parseInt(''01'', 2) = " + parseInt(''01'', 2) + "<br>" + "parseInt(''1'', 2) = " + parseInt(''1'', 2) + "<br>" + "parseInt(''A'', 10) = " + parseInt(''A'', 10) + "<br>" + "parseInt(''A'', 11) = " + parseInt(''A'', 11) + "<br>" + "parseInt(''Z'', 36) = " + parseInt(''Z'', 36) + "<br><br>" + "<b>The value:</b><br>" + "parseInt(''A'', 11) = " + parseInt(''A'', 11) + "<br>" + "parseInt(''A'', 12) = " + parseInt(''A'', 12) + "<br>" + "parseInt(''A'', 13) = " + parseInt(''A'', 13) + "<br>" + "parseInt(''AA'', 11) = " + parseInt(''AA'', 11) + " = 100 + 20" + "<br>" + "parseInt(''AA'', 12) = " + parseInt(''AA'', 12) + " = 100 + 30" + "<br>" + "parseInt(''AA'', 13) = " + parseInt(''AA'', 13) + " = 100 + 40" + "<br>" + "parseInt(''AAA'', 11) = " + parseInt(''AAA'', 11) + " = 1000 + 300 + 30" + "<br>" + "parseInt(''AAA'', 12) = " + parseInt(''AAA'', 12) + " = 1000 + 500 + 70" + "<br>" + "parseInt(''AAA'', 13) = " + parseInt(''AAA'', 13) + " = 1000 + 700 + 130" + "<br>" + "parseInt(''AAA'', 14) = " + parseInt(''AAA'', 14) + " = 1000 + 900 + 210" + "<br>" + "parseInt(''AAA'', 15) = " + parseInt(''AAA'', 15) + " = 1000 + 1100 + 310";


For radices above 10, the letters of the alphabet indicate numerals greater than 9. For example, for hexadecimal numbers (base 16), A through F are used.

En su cadena dsff66 , d es un carácter hexadecimal (aunque la cadena no es hexadecimal) que se ajusta al tipo de raíz y es equivalente al número 13 . Deja de analizar después de eso, ya que el siguiente carácter no es hexadecimal, de ahí el resultado.


parseInt lee la entrada hasta que encuentra un carácter no válido, y luego utiliza la entrada válida que leyó antes de ese carácter no válido. Considerar:

parseInt("17days", 10);

Esto usará la entrada 17 y omitirá todo después de la d inválida.

De la ecma-international.org/ecma-262/5.1/#sec-15.1.2.2 :

Si [la cadena de entrada] S contiene cualquier carácter que no sea un dígito de la raíz-R, entonces Z [la cadena a ser integer] es la subcadena de S que consta de todos los caracteres antes del primer carácter ; de lo contrario, sea Z sea S.

En su ejemplo, s es un carácter base-16 no válido, por lo que parseInt usa solo la d .

En cuanto a por qué se incluyó este comportamiento: no hay forma de saberlo con certeza, pero es probable que se trate de un intento de reproducir el comportamiento de strtol (cadena a largo) desde la biblioteca estándar de C. Desde la página del manual de strtol(3) :

... la cadena se convierte a un valor int largo de la manera obvia, deteniéndose en el primer carácter que no es un dígito válido en la base dada .

Esta conexión también es compatible (hasta cierto punto) con el hecho de que tanto parseInt como strtol están especificados para ignorar los espacios en blanco iniciales, y ambos pueden aceptar un 0x para los valores hexadecimales.