Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why use decimal(int [ ]) constructor?

I am maintaining a C# desktop application, on windows 7, using Visual Studio 2013. And somewhere in the code there is the following line, that tries to create a 0.01 decimal value, using a Decimal(Int32[]) constructor:

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

First question is, is it different from the following?

decimal d = 0.01M;

If it is not different, why the developer has gone through the trouble of coding like that?

I need to change this line in order to create dynamic values. Something like:

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

Am I going to cause some unwanted behavior this way?

like image 353
Makan Tayebi Avatar asked Apr 15 '16 13:04

Makan Tayebi


People also ask

What is decimal in C#?

In C#, Decimal Struct class is used to represent a decimal floating-point number. The range of decimal numbers is +79,228,162,514,264,337,593,543,950,335 to -79,228,162,514,264,337,593,543,950,335.

How do you initialize decimals?

To initialize a decimal variable, use the suffix m or M. Like as, decimal x = 300.5m;. If the suffix m or M will not use then it is treated as double. Character Types : The character types represents a UTF-16 code unit or represents the 16-bit Unicode character.

How do you define decimals in Python?

In Python, there is a module called Decimal, which is used to do some decimal floating point related tasks. This module provides correctly-rounded floating point arithmetic. To use it at first we need to import it the Decimal standard library module.


4 Answers

It seems useful to me when the source of the decimal consists of bits.

The decimal used in .NET has an implementation that is based on a sequence of bit parameters (not just one stream of bits like with an int), so it can be useful to construct a decimal with bits when you communicate with other systems which return a decimal through a blob of bytes (a socket, from a piece of memory, etc).

It is easy now to convert the set of bits to a decimal now. No need for fancy conversion code. Also, you can construct a decimal from the inputs defined in the standard, which makes it convenient for testing the .NET framework too.

like image 126
Patrick Hofman Avatar answered Oct 13 '22 21:10

Patrick Hofman


The decimal(int[] bits) constructor allows you to give a bitwise definition of the decimal you're creating bits must be a 4 int array where:

bits 0, 1, and 2 make up the 96-bit integer number.

bits 3 contains the scale factor and sign

It just allows you to get really precise with the definition of the decimal judging from your example I don't think you need that level of precision.

See here for more detail on using that constructor or here for other constructors that may be more appropriate for you

To more specifically answer your question if digitNumberis a 16bit exponent then decimal d = new decimal(new int[] { 1, 0, 0, digitNumber << 16 }); does what you want since the exponent goes in bits 16 - 23 of last int in the array

like image 37
HasaniH Avatar answered Oct 13 '22 21:10

HasaniH


The definition in the xml is

    //
    // 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.

So for some unknown reason the original developer wanted to initialize his decimal this way. Maybe he was just wanted to confuse someone in the future.

It cant possibly affect your code if you change this to

decimal d = 0.01m;

because

(new decimal(new int[] { 1, 0, 0, 131072})) == 0.01m
like image 30
CathalMF Avatar answered Oct 13 '22 21:10

CathalMF


You should exactly know how decimal stored in memory.

you can use this method to generate the desired value

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 });
}

Use it like

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

Here is the result

1
0.01
0.00001

like image 44
Hamid Pourjam Avatar answered Oct 13 '22 22:10

Hamid Pourjam