c# - que - ¿Cómo determinar si un decimal/doble es un número entero?
que es double en programacion (14)
¿Qué tal esto?
public static bool IsInteger(double number) {
return number == Math.Truncate(number);
}
Mismo código para decimal
Mark Byers hizo un buen punto, en realidad: esto puede no ser lo que realmente quieres. Si lo que realmente te importa es si un número redondeado a los dos lugares decimales más cercanos es un número entero , puedes hacer esto en su lugar:
public static bool IsNearlyInteger(double number) {
return Math.Round(number, 2) == Math.Round(number);
}
¿Cómo puedo saber si un valor decimal o doble es un número entero?
Por ejemplo:
decimal d = 5.0; // Would be true
decimal f = 5.5; // Would be false
o
double d = 5.0; // Would be true
double f = 5.5; // Would be false
La razón por la que me gustaría saber esto es para poder determinar mediante programación si quiero generar el valor usando .ToString("N0")
o .ToString("N2")
. Si no hay un valor de punto decimal, entonces no quiero mostrar eso.
El uso de int.TryParse arrojará estos resultados: var shouldBeInt = 3;
var shouldntBeInt = 3.1415;
var iDontWantThisToBeInt = 3.000f;
Console.WriteLine(int.TryParse(shouldBeInt.ToString(), out int parser)); // true
Console.WriteLine(int.TryParse(shouldntBeInt.ToString(), out parser)); // false
Console.WriteLine(int.TryParse(iDontWantThisToBeInt.ToString(), out parser)); // true, even if I don''t want this to be int
Console.WriteLine(int.TryParse("3.1415", out parser)); // false
Console.WriteLine(int.TryParse("3.0000", out parser)); // false
Console.WriteLine(int.TryParse("3", out parser)); // true
Console.ReadKey();
Enfrenté una situación similar, pero donde el valor es una cadena. El usuario escribe un valor que se supone que es un monto en dólares, por lo que quiero validar que sea numérico y que tenga como máximo dos decimales.
Este es mi código para devolver verdadero si la cadena "s" representa un valor numérico con un máximo de dos decimales, y de lo contrario es falso. Evita cualquier problema que resulte de la imprecisión de los valores de coma flotante.
try
{
// must be numeric value
double d = double.Parse(s);
// max of two decimal places
if (s.IndexOf(".") >= 0)
{
if (s.Length > s.IndexOf(".") + 3)
return false;
}
return true;
catch
{
return false;
}
Discuto esto con más detalle en http://progblog10.blogspot.com/2011/04/determining-whether-numeric-value-has.html .
Hay varias maneras de hacer esto. Por ejemplo:
double d = 5.0;
bool isInt = d == (int)d;
También puedes usar modulo.
double d = 5.0;
bool isInt = d % 1 == 0;
La respuesta de Mark Rushakoff puede ser más simple, pero los siguientes también funcionan y pueden ser más eficientes ya que no hay una operación de división implícita:
bool isInteger = (double)((int)f) == f ;
y
bool isInteger = (decimal)((int)d) == d ;
Si quieres una sola expresión para ambos tipos, quizás
bool isInteger = (double)((int)val) == (double)val ;
Para números de punto flotante, n % 1 == 0
es típicamente la forma de verificar si hay algo más allá del punto decimal.
public static void Main (string[] args)
{
decimal d = 3.1M;
Console.WriteLine((d % 1) == 0);
d = 3.0M;
Console.WriteLine((d % 1) == 0);
}
Salida:
False
True
Actualización: Como @Adrian Lopez mencionó a continuación, la comparación con un epsilon
pequeño valor descartará los cálculos erróneos de computación en coma flotante. Dado que la pregunta es acerca de los valores double
, a continuación se mostrará una respuesta de prueba de cálculo con coma flotante :
Math.Abs(d % 1) <= (Double.Epsilon * 100)
Podría usar el método ''TryParse''.
int.TryParse()
Esto verifica si el valor se puede convertir a un valor de número entero entero. El resultado puede indicar una bandera que se puede usar en cualquier otro lugar de su código.
Prueba esto:
number == Convert.ToInt16(number);
Puede usar el formato de cadena para el tipo doble. Aquí hay un ejemplo:
double val = 58.6547;
String.Format("{0:0.##}", val);
//Output: "58.65"
double val = 58.6;
String.Format("{0:0.##}", val);
//Output: "58.6"
double val = 58.0;
String.Format("{0:0.##}", val);
//Output: "58"
Avísame si esto no ayuda.
Quizás no sea la solución más elegante, ¡pero funciona si no eres demasiado quisquilloso!
bool IsInteger(double num) {
return !num.ToString("0.################").Contains(".");
}
Si bien las soluciones propuestas parecen funcionar para ejemplos simples, hacer esto en general es una mala idea. Es posible que un número no sea exactamente un número entero, pero cuando intenta formatearlo, está lo suficientemente cerca de un número entero que obtiene 1.000000
. Esto puede suceder si se hace un cálculo que en teoría debería dar exactamente 1, pero en la práctica da un número muy cercano pero no exactamente igual a uno debido a errores de redondeo.
En su lugar, formatee primero y si su cadena termina en un período seguido de ceros, quítelos. También hay algunos formatos que puede usar que eliminan ceros finales automáticamente. Esto podría ser lo suficientemente bueno para su propósito.
double d = 1.0002;
Console.WriteLine(d.ToString("0.##"));
d = 1.02;
Console.WriteLine(d.ToString("0.##"));
Salida:
1
1.02
Si el límite superior e inferior de Int32
importa:
public bool IsInt32(double value)
{
return value == (int)value && value >= int.MinValue && value <= int.MaxValue;
}
bool IsInteger(double num) {
if (ceil(num) == num && floor(num) == num)
return true;
else
return false;
}
Problemo solvo.
Editar: Creado por Mark Rushakoff.
static bool IsWholeNumber(double x)
{
return Math.Abs(x % 1) < double.Epsilon;
}