如何在<int> F# 中创建从指针到十进制变量的 Span?



在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包安装,如果目标是旧的框架

最新更新