Skip to content

Commit 06f31b6

Browse files
authored
Merge pull request #1512 from microsoft/user/jevansaks/decimalcleanup
Simplify decimal conversions
1 parent 287d840 commit 06f31b6

3 files changed

Lines changed: 16 additions & 31 deletions

File tree

Lines changed: 6 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,16 @@
11
internal partial struct DECIMAL
22
{
3-
public DECIMAL(decimal value)
3+
public unsafe DECIMAL(decimal value)
44
{
5-
unchecked
6-
{
7-
const int SignMask = (int)0x80000000;
8-
#if NET5_0_OR_GREATER
9-
Span<int> bits = stackalloc int[4];
10-
decimal.GetBits(value, bits);
11-
#else
12-
int[] bits = decimal.GetBits(value);
13-
#endif
14-
uint lo32 = (uint)bits[0];
15-
uint mid32 = (uint)bits[1];
16-
uint hi32 = (uint)bits[2];
17-
byte scale = (byte)(bits[3] >> 16);
18-
byte sign = (bits[3] & SignMask) == SignMask ? (byte)0x80 : (byte)0x00;
19-
this.Anonymous2 = new _Anonymous2_e__Union() { Anonymous = new _Anonymous2_e__Union._Anonymous_e__Struct() { Lo32 = lo32, Mid32 = mid32 } };
20-
this.Hi32 = hi32;
21-
this.Anonymous1 = new _Anonymous1_e__Union() { Anonymous = new _Anonymous1_e__Union._Anonymous_e__Struct() { scale = scale, sign = sign } };
22-
this.wReserved = 0;
23-
}
5+
// DECIMAL is layout-compatible with decimal.
6+
this = *(DECIMAL*)&value;
247
}
258

26-
public static implicit operator decimal(DECIMAL value)
9+
public static unsafe implicit operator decimal(DECIMAL value)
2710
{
28-
return new decimal(
29-
(int)value.Anonymous2.Anonymous.Lo32,
30-
(int)value.Anonymous2.Anonymous.Mid32,
31-
(int)value.Hi32,
32-
value.Anonymous1.Anonymous.sign == 0x80,
33-
value.Anonymous1.Anonymous.scale);
11+
// DECIMAL is layout-compatible with decimal.
12+
return *(decimal*)&value;
3413
}
3514

36-
#if NET5_0_OR_GREATER
3715
public static implicit operator DECIMAL(decimal value) => new DECIMAL(value);
38-
#endif
3916
}

test/GenerationSandbox.Tests/BasicTests.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,9 @@ public void DecimalConversion(decimal value)
153153
decimal valueRoundTripped = nativeDecimal;
154154
Assert.Equal(value, valueRoundTripped);
155155

156-
#if NET5_0_OR_GREATER
157156
nativeDecimal = value;
158157
valueRoundTripped = nativeDecimal;
159158
Assert.Equal(value, valueRoundTripped);
160-
#endif
161159
}
162160

163161
[Fact]

test/Microsoft.Windows.CsWin32.Tests/GeneratorTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ public void SimplestMethod(string tfm)
8282
}
8383
}
8484

85+
[Fact]
86+
public void DecimalWorksInNet35()
87+
{
88+
this.compilation = this.starterCompilations["net35"];
89+
this.generator = this.CreateGenerator();
90+
Assert.True(this.generator.TryGenerate("VarDecDiv", CancellationToken.None));
91+
this.CollectGeneratedCode(this.generator);
92+
this.AssertNoDiagnostics();
93+
}
94+
8595
[Fact]
8696
public void DbgHelpExternMethodsCanLoadAppLocal()
8797
{

0 commit comments

Comments
 (0)