在c#中我可以这样做:
decimal v = 123.456M;
var span = new ReadOnlySpan<int>(&v, 4);
var flags = span[0];
var hi32 = span[1];
var lo32 = span[2];
var mi32 = span[3];
是否有一种方法可以在f# 5.0中做同样的事情?
背景:我在尝试移植小数点。IsCanonical方法从。net 7到。net Framework 4.7.2和f# 5.0。所以我需要访问一个十进制数的内部表示。该方法将在热路径上使用,因此我希望避免使用Decimal.GetBits()方法,因为它分配了一个数组。
可以从指针和长度创建span,但是公共构造函数的可用性因目标框架版本而异
open System
open System.Runtime.CompilerServices
open System.Runtime.InteropServices
let newer (d:decimal) = // netstandard2.1 and newer (net core 3.1, net5.0)
let span = ReadOnlySpan<int>(Unsafe.AsPointer(&Unsafe.AsRef &d), 4)
let flags = span.[0]
let hi32 = span.[1]
let lo32 = span.[2]
let mi32 = span.[3]
()
let older (d:decimal) = // before span ctor become public (net framework and netstandard2.0)
let span = MemoryMarshal.CreateSpan(&Unsafe.As<_, int>(&Unsafe.AsRef &d), 4)
let flags = span.[0]
let hi32 = span.[1]
let lo32 = span.[2]
let mi32 = span.[3]
()
注意:System.Runtime.CompilerServices.Unsafe
必须作为nuget包安装,如果目标是旧的框架