Mientras programaba en C ++ hace unos días, cometí este error (¡tengo antecedentes de hacerlo!). En una parte de mi código, tenía 1/6 y esperaba que fuera 0.16666666666, que no es el caso. Como todos saben, el resultado es 0 - C, C ++, Java, Python, todos se comportan igual.
Lo publico en mi página de Facebook y ahora hay un debate sobre si hay un lenguaje de programación en el que se 1/6
comporta igual 1.0/6.0
.
programming-languages
Pouya
fuente
fuente
>> 1 / 6
->== 0.166666666666667
1/6
es en realidad 1/6 (tipo fraccional) que, forzadoDouble
, es 1.66666 ...Respuestas:
¿Todos han olvidado a Pascal?
1/6
rendimientos0.1666666...
(con la precisión que sea compatible).1 div 6
rendimientos0
Es discutible si la regla C es un error. Casi todos los operadores aritméticos de C, donde los operandos son del mismo tipo, producen un resultado del mismo tipo. Hay algo que decir por consistencia.
Además, dado que C está dirigido principalmente a código de nivel de sistema, la mayoría de los programas de C no usan punto flotante en absoluto. En un momento, agregar accidentalmente código de punto flotante a un programa que de otro modo no lo necesitaría podría ser un problema grave. Probablemente ese sea el caso para los pequeños sistemas integrados, que, una vez más, son un objetivo importante para C.
En la mayoría de los programas en C, la división de números enteros truncados es probablemente lo que desea de todos modos.
Si
1 / 6
arrojó un resultado de coma flotante en C, entonces:double
puede parecer la opción natural, pero es posible que prefiera la precisión adicional delong double
)C podría haber proporcionado operadores separados para los dos tipos de división, pero el segundo punto anterior aún se aplicaría: ¿cuál de los tres tipos de coma flotante se usaría para el resultado? Y dado que es bastante fácil obtener una división de punto flotante si la necesita (use una constante de punto flotante para uno o ambos operandos, o convierta uno o ambos operandos en un tipo de punto flotante), aparentemente no era No lo consideró tan importante.
En la versión de 1974 del manual C (4 años antes de la publicación de la primera edición de K&R), Ritchie ni siquiera menciona la posible confusión:
que dice que si ambos operandos son de tipo
int
ochar
, el resultado es de tipoint
.Sí, es una fuente de confusión para algunos programadores de C, especialmente para principiantes, pero C no se destaca por ser muy amigable para los novatos.
fuente
1.666666...
, lo cual es claramente incorrecto. Mi pobre excusa es que el programa de prueba Pascal que escribí impreso1.6666666666666667E-0001
En realidad, este comportamiento se cambió en Python 3 y ahora se comporta como esperabas (
//
ahora se usa para la división de enteros).fuente
/
siempre produce un valor de punto flotante, ydiv
se utiliza un operador separado ( ) para la división de enteros.Fuera de lenguajes destacados, JavaScript. 1.0 / 6.0 = 1/6 = 0.16666666666666666.
No veo esto como sorprendente. Como regla general, si un lenguaje distingue entre tipos numéricos de enteros y de coma flotante, dividir dos enteros producirá un entero truncado en lugar de flotante. Si no es así, lo más probable es que se convierta en operaciones de punto flotante. Este debería ser el comportamiento esperado por parte del programador.
Solo tenga en cuenta que hay cosas adicionales que también podrían estar en juego aquí, como el operador de división de enteros separado ya mencionado o el tipo de conversión implícito.
fuente
Hay muchos idiomas donde los
((1/6)*6)
resultados son 1, no 0. Por ejemplo, PL / SQL, muchos dialectos BÁSICOS, Lua.Accidentalmente, en todos esos idiomas, 1/6 resulta en .166666667, o 0.16666666666667 o algo similar. Elegí la variante ((1/6) * 6) == 1 para deshacerme de esas pequeñas diferencias.
fuente
((1/6)*6)==1
variante para deshacerme de esas pequeñas diferencias, pero parece que sobreestimé las habilidades matemáticas de algunas personas.Haskell trata 1/6 y 1.0 / 6.0 como idénticamente 0.16666666666666666. También representa 1 / 6.0 y 1.0 / 6 como el mismo valor también.
Esto se debe a que los tipos numéricos básicos en Haskell no son exactamente iguales a otros idiomas. La verdadera división entera es algo ... complicada.
fuente
Sí, lo hace Perl. El one-liner
da como resultado la salida de:
Creo que PHP funciona de la misma manera.
Editado para agregar: también creo que una condición necesaria (pero no suficiente)
1/6 == 1.0/6.0
es que el idioma en cuestión se tipee débilmente.fuente
/
se sobrecargue automáticamente dependiendo de los tipos de argumentos, pero eso parece una violación del Principio de Menos Asombro para yo ...En Squeak Smalltalk
/
en enteros crea objetos Fraction. Entonces, si bien esto no es lo mismo que la división de flotación, aún(1/6)*6
devuelve 1.fuente
Sí, acabo de comprobar que mi TI-99 / 4A está integrada en TI BASIC . Como trata todas las expresiones numéricas como punto flotante, la operación de división también es punto flotante.
fuente
VB ( VB.Net , VB6 , VBA ...)
El operador de división entera es \
fuente
MATLAB Los literales numéricos son dobles por defecto.
fuente
Clojure usa fracciones por defecto. No es lo mismo que 1.0 / 6.0, pero puede convertirlo con
float
odouble
cuando lo necesite.fuente
Sorprendentemente, parece funcionar correctamente en Windows PowerShell (versión 3) .
También parece funcionar en Python 3 como sepp2k mencionado. Los otros dos idiomas que tengo disponibles en REPL, Scala y Ruby, ambos hacen división entera y producen 0.
fuente
El lenguaje Rexx siempre produce una respuesta aritméticamente correcta. Por ejemplo: 5/2 = 2.5. Rexx es un gran lenguaje que no se ha utilizado lo suficiente. En teoría, cuando un compilador no puede determinar qué quiere, es mejor hacer las matemáticas correctas, sin embargo, esto puede no ser eficiente. Rexx también proporciona el operador //.
fuente