Подтвердить что ты не робот

Зачем использовать десятичный (int []) конструктор?

Я поддерживаю настольное приложение С# в Windows 7 с помощью Visual Studio 2013. И где-то в коде есть следующая строка, которая пытается создать десятичное значение 0.01, используя конструктор Decimal (Int32 []):

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

Первый вопрос: отличается ли он от следующего?

decimal d = 0.01M;

Если это не так, почему разработчик преодолел проблемы с кодированием?

Мне нужно изменить эту строку, чтобы создать динамические значения. Что-то вроде:

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

Я собираюсь вызвать какое-то нежелательное поведение таким образом?

4b9b3361

Ответ 1

Конструктор decimal(int[] bits) позволяет вам поразрядное определение десятичного числа, которое вы создаете, должно быть 4 массивом int, где:

бит 0, 1 и 2 составляют 96-битное целочисленное число.

бит 3 содержит масштабный коэффициент и знак

Он просто позволяет вам получить точную информацию с определением десятичного суждения из вашего примера. Я не думаю, что вам нужен этот уровень точности.

См. здесь для более подробной информации об использовании этого конструктора или здесь для других конструкторов, которые могут быть более подходящими для вас

Чтобы более точно ответить на ваш вопрос, если digitNumber - показатель 16 бит, тогда decimal d = new decimal(new int[] { 1, 0, 0, digitNumber << 16 }); делает то, что вы хотите, так как экспонент идет в битах 16-23 последнего int в массиве

Ответ 2

Мне кажется полезным, когда источник десятичной дроби состоит из битов.

У десятичного числа, используемого в .NET, есть реализация, основанная на последовательности битовых параметров (а не только на одном потоке битов, например, с int), поэтому может быть полезно создать десятичную дробь с битами при общении с другими системами, которые возвращают десятичное число через кусок байта (сокет, из куска памяти и т.д.).

Теперь легко преобразовать набор бит в десятичный. Нет необходимости в причудливом конверсионном коде. Кроме того, вы можете построить десятичную дробь из входов, определенных в стандарте, что также удобно для тестирования среды .NET.

Ответ 3

Определение в xml

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

Итак, по какой-то неизвестной причине первоначальный разработчик захотел инициализировать его десятичную такту. Может быть, он просто хотел кого-то запутать в будущем.

Возможно, это повлияет на ваш код, если вы измените его на

decimal d = 0.01m;

потому что

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

Ответ 4

Вы должны точно знать, как десятичный хранится в памяти.

вы можете использовать этот метод для генерации желаемого значения

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

Используйте его как

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

Вот результат

1
0.01
0,00001

Ответ 5

Конкретный конструктор, о котором вы говорите, генерирует десятичный знак из четырех 32-битных значений. К сожалению, более новые версии Common Language Infrastructure (CLI) оставляют свой точный формат неопределенным (предположительно, чтобы позволить реализациям поддерживать разные десятичные форматы) и теперь просто гарантируют по крайней мере определенную точность и диапазон десятичных чисел. Однако более ранние версии CLI определяют этот формат точно так же, как это делает реализация Microsoft, поэтому он, вероятно, сохранил этот путь в реализации Microsoft для обратной совместимости. Однако не исключено, что другие реализации CLI будут интерпретировать четыре 32-битных значения конструктора Decimal по-разному.

Ответ 6

Десятичные числа - это точные цифры, вы можете использовать == или!= для проверки равенства.

Возможно, эта строка кода исходит из какого-то другого места, где это имело смысл в какой-то определенный момент времени.

Я бы очистил его.