|
1 | 1 | internal partial struct DECIMAL |
2 | 2 | { |
3 | | - public DECIMAL(decimal value) |
| 3 | + public unsafe DECIMAL(decimal value) |
4 | 4 | { |
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; |
24 | 7 | } |
25 | 8 |
|
26 | | - public static implicit operator decimal(DECIMAL value) |
| 9 | + public static unsafe implicit operator decimal(DECIMAL value) |
27 | 10 | { |
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; |
34 | 13 | } |
35 | 14 |
|
36 | | -#if NET5_0_OR_GREATER |
37 | 15 | public static implicit operator DECIMAL(decimal value) => new DECIMAL(value); |
38 | | -#endif |
39 | 16 | } |
0 commit comments