visual valid remarks generate example documentacion cref comment comentarios c# .net refactoring decimal

c# - valid - ¿Por qué usar el constructor decimal(int[])?



remarks c# (6)

Estoy manteniendo una aplicación de escritorio C #, en Windows 7, usando Visual Studio 2013. Y en alguna parte del código está la siguiente línea, que intenta crear un valor decimal de 0.01, usando un constructor de Decimal (Int32 []):

decimal d = new decimal(new int[] { 1, 0, 0, 131072 });

La primera pregunta es, ¿es diferente de la siguiente?

decimal d = 0.01M;

Si no es diferente, ¿por qué el desarrollador ha pasado por el problema de codificar así?

Necesito cambiar esta línea para crear valores dinámicos. Algo como:

decimal d = (decimal) (1 / Math.Pow(10, digitNumber));

¿Voy a causar algún comportamiento no deseado de esta manera?


El constructor decimal(int[] bits) permite dar una definición a nivel de bits del decimal que está creando. Los bits deben ser una matriz de 4 int donde:

los bits 0, 1 y 2 forman el número entero de 96 bits.

los bits 3 contienen el factor de escala y el signo

Simplemente le permite ser realmente preciso con la definición del decimal a partir de su ejemplo. No creo que necesite ese nivel de precisión.

Consulte aquí para obtener más detalles sobre el uso de ese constructor o here para otros constructores que pueden ser más apropiados para usted

Para responder más específicamente a su pregunta si digitNumber es un exponente de 16 bits, entonces decimal d = new decimal(new int[] { 1, 0, 0, digitNumber << 16 }); hace lo que quiere ya que el exponente va en los bits 16 - 23 de la última int en la matriz


El constructor particular del que estás hablando genera un decimal a partir de cuatro valores de 32 bits. Desafortunadamente, las versiones más recientes de Common Language Infrastructure (CLI) dejan su formato exacto sin especificar (presumiblemente para permitir que las implementaciones admitan diferentes formatos decimales) y ahora simplemente garantizan al menos una precisión específica y un rango de números decimales. Sin embargo, las versiones anteriores de la CLI sí definen ese formato exactamente como lo hace la implementación de Microsoft, por lo que probablemente se mantenga de esa manera en la implementación de Microsoft para la compatibilidad con versiones anteriores. Sin embargo, no se descarta que otras implementaciones de la CLI interpretarán los cuatro valores de 32 bits del constructor decimal de manera diferente.


La definición en el xml es

// // Summary: // Initializes a new instance of System.Decimal to a decimal value represented // in binary and contained in a specified array. // // Parameters: // bits: // An array of 32-bit signed integers containing a representation of a decimal // value. // // Exceptions: // System.ArgumentNullException: // bits is null. // // System.ArgumentException: // The length of the bits is not 4.-or- The representation of the decimal value // in bits is not valid.

Así que por alguna razón desconocida, el desarrollador original quería inicializar su decimal de esta manera. Tal vez solo quería confundir a alguien en el futuro.

Posiblemente no pueda afectar su código si cambia esto a

decimal d = 0.01m;

porque

(new decimal(new int[] { 1, 0, 0, 131072})) == 0.01m


Los decimales son números numéricos exactos, puede usar == o! = Para probar la igualdad.

Tal vez, esta línea de código proviene de algún otro lugar donde tenía sentido en algún momento particular del tiempo.

Yo lo limpiaría.


Me parece útil cuando la fuente del decimal consiste en bits.

El decimal utilizado en .NET tiene una implementación que se basa en una secuencia de parámetros de bits (no solo un flujo de bits como con un int ), por lo que puede ser útil construir un decimal con bits cuando se comunica con otros sistemas que devuelven un decimal a través de un blob de bytes (un socket, desde un trozo de memoria, etc.).

Ahora es fácil convertir el conjunto de bits a un decimal. No hay necesidad de código de conversión de lujo. Además, puede construir un decimal a partir de las entradas definidas en el estándar, lo que lo hace conveniente para probar el marco .NET también.


Usted debe saber exactamente cómo se almacena el decimal en la memoria.

Puedes usar este método para generar el valor deseado.

public static decimal Base10FractionGenerator(int digits) { if (digits < 0 || digits > 28) throw new ArgumentException($"''{nameof(digits)}'' must be between 0 and 28"); return new decimal(new[] { 1, 0, 0, digits << 16 }); }

Utilízalo como

Console.WriteLine(Base10FractionGenerator(0)); Console.WriteLine(Base10FractionGenerator(2)); Console.WriteLine(Base10FractionGenerator(5));

Aquí está el resultado.

1
0.01
0.00001