Тип decimal
представлен целым числом масштабируется с коэффициентом 10. Из документации decimal
:
Масштабирование фактор также сохраняет любые конечные нули в десятичном числе. Конечные нули не влияют на значение десятичного числа в арифметических или сравнительных операциях. Однако конечные нули могут быть обнаружены методом ToString, если применяется соответствующая строка формата.
Использование GetBits
вы можете увидеть, что 123.00M
представлен как 12300/10 в то время как 123M
составляет 123/10 .
Редактировать
Я взял простую программу, которая demostrates вопрос:
class Program
{
static void Main(string[] args)
{
Console.WriteLine((1.23M * 100M).ToString());
Console.WriteLine((123M).ToString());
}
}
Я смотрел на сгенерированный IL:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 51 (0x33)
.maxstack 6
.locals init ([0] valuetype [mscorlib]System.Decimal CS$0$0000)
IL_0000: nop
IL_0001: ldc.i4 0x300c
IL_0006: ldc.i4.0
IL_0007: ldc.i4.0
IL_0008: ldc.i4.0
IL_0009: ldc.i4.2
IL_000a: newobj instance void [mscorlib]System.Decimal::.ctor(int32,
int32,
int32,
bool,
uint8)
IL_000f: stloc.0
IL_0010: ldloca.s CS$0$0000
IL_0012: call instance string [mscorlib]System.Decimal::ToString()
IL_0017: call void [mscorlib]System.Console::WriteLine(string)
IL_001c: nop
IL_001d: ldc.i4.s 123
IL_001f: newobj instance void [mscorlib]System.Decimal::.ctor(int32)
IL_0024: stloc.0
IL_0025: ldloca.s CS$0$0000
IL_0027: call instance string [mscorlib]System.Decimal::ToString()
IL_002c: call void [mscorlib]System.Console::WriteLine(string)
IL_0031: nop
IL_0032: ret
} // end of method Program::Main
Мы можем видеть, что компилятор на самом деле оптимизированы отмените умножение и вставили вызов конструкции одного десятичного экземпляра для первого случая. Два экземпляра используют разные представления. В основном это то, что я описал выше.
Существует документация по этому вопросу, но, к сожалению, фактическое поведение не соответствует 100% спецификации. –