我发现CIL compiller允许类型native float.但是,CLR不允许这样做.它有用吗?它的大小是多少?是否有相应的.NET类型?我试图将它实现为伪原始类型:
.class public sequential ansi serializable sealed beforefieldinit NativeFloat
extends System.ValueType
{
.field assembly native float m_value
}
Run Code Online (Sandbox Code Playgroud)
但是,CLR不支持此类型.谢谢您的帮助.
编辑:如果你有兴趣,它的CorElementType是26(0x1a,R).
来自CIL ECMA规范,I.12.1.1本机大小:native int,native unsigned int,O和&:
原生大小类型(native int,native unsigned int,O和&)是CLI中用于推迟选择值大小的机制.这些数据类型以CIL类型存在; 但是,CLI会将每个映射到特定处理器的本机大小.(例如,数据类型I将映射到奔腾处理器上的int32,但是映射到IA64处理器上的int64.)因此,大小的选择推迟到JIT编译或运行时,CLI初始化并且架构已知.这意味着在编译时也不知道字段和堆栈帧偏移.
现在,已经说过,native float(而不是native int)在ECMA规范中没有提到过一次.我能找到的唯一证据是在一些开源CIL汇编程序中,它们抛出异常表明它们无法生成操作码native float.
如果微软的CIL编译器确实接受了这种类型,我会想象这是微软打算实现的一个功能,但最终并未最终投入MSIL(CIL的前身).另外,如果汇编程序实际上产生了操作码而不是错误消息,我可以想象(尽管这也是猜测)可能存在Microsoft的CLR(可能是.NET Micro Framework或特定版本的Silverlight)的变体,或者什么)支持操作码.
另请注意,在上面的规范中,提到了CLI.CLR仅仅是Microsoft的CLI实现.
ECMA规范确实提到了本机浮点类型,但它不是native float:
F,浮点值(float32,float64或底层硬件支持的其他表示)
CLI规范Ecma 335定义了三种浮点类型.Float32,float64和F.前两个是名义类型,第三个是表示类型,IL中的"本机浮点"类型.
第I.12.1.3节"浮点数据类型的处理"给出了基本原理:
浮点数(静态,数组元素和类的字段)的存储位置具有固定大小.支持的存储大小为float32和float64.其他地方(在评估堆栈上,作为参数,作为返回类型和作为局部变量)浮点数使用内部浮点类型表示.在每个这样的实例中,变量或表达式的标称类型是float32或float64,但其值可以在内部用额外的范围和/或精度表示.内部浮点表示的大小取决于实现,可以变化,并且其精度至少与表示的变量或表达式的精度一样大.
这在当前的jitter实现中实际上并不存在,参数和局部变量实际上是float32或float64.但是它有一些先例,并且他们首先考虑这个问题的可能原因是,英特尔处理器中的内部FPU寄存器是80位.这是英特尔设计8087协处理器时许多月前的设计决策.
这个想法在纸面上听起来很不错,它允许以更高的精度存储中间计算结果,因此计算的最终结果可能更准确.然而毫无疑问,英特尔的十亿美元错误,FPU无法优化,仍然允许一致的浮点结果.问题在于内部FPU寄存器是有限的资源,其中只有8个.它也被实现为堆栈,处理起来非常尴尬.如果涉及计算,则不可避免地需要将中间结果溢出到存储器中.将80位值截断为64位.如果计算容易丢失很多有效数字,那么对代码进行小的更改会在计算结果中产生很大的差异.或者通常会扰乱程序员,因为第16位数字不一样.
那么,大错,也是SO的大量问题的根源.当英特尔实施下一代浮点硬件时,该想法被废弃,XMM和YMM寄存器为64位.真正的寄存器,而不是堆栈.x64抖动使用它们.使程序在64位模式下运行会产生与在32位模式下运行时不同的结果.还需要十年才能停止伤害.
| 归档时间: |
|
| 查看次数: |
641 次 |
| 最近记录: |