请注意,我不是在寻找基于意见或某些第三方库的东西 - 我只是想确认没有任何计划(或指向权力的某些讨论).我试过谷歌并没有找到任何东西,所以看起来我正朝着"使用英特尔库在C++/CLI中编写我自己的实现").
像许多人一样,我正在处理财务数据,这意味着花车存在极大的问题.同时,.NET十进制是一个野兽 - 慢而且大(128位大)这使得当你收集成千上万的它们并希望它们在一个包含更多信息的结构中时使用它是低效的.
IEEE 754定义了3种十进制类型,它们可能在主流处理器的硬件中得到支持(例如,它们已经具有较少的通用功能,例如Power系列),支持32位,64位和128位.有一个优化的英特尔库可以进行十进制数学运算,很可能在某一点上至少有更简单的数学将在硬件中.
我所能找到的只是Annotated C#Standard中关于.NET十进制与IEEE当时提出的标准之间的互操作的古老讨论,并且它被拒绝但是以某种方式可以确定位域是.NET小数还是bit inveted IEEE decimal 128.
从那时起,许多年过去了.现在IEEE 754:2008已经完成 - 我想知道是否有任何关于如何继续发布的官方文章.正如我所说的那样,.NET十进制数字很慢,并且没有机会获得硬件加速 - 而且我的表现非常大.
那么,任何人都知道博客中的任何东西?注意 - 它必须是官方的或指的,我不是来自与.NET语言或BCL团队无关的人的意见.这是关于规范资源,是否将来考虑其他数据类型......可能是针对.NET 5.0/6.0时间帧.
Google的协议缓冲区允许您在邮件中存储浮点数和双精度数.我查看了实现源代码,想知道他们是如何以跨平台的方式设法做到这一点的,我偶然发现的是:
inline uint32 WireFormatLite::EncodeFloat(float value) {
union {float f; uint32 i;};
f = value;
return i;
}
inline float WireFormatLite::DecodeFloat(uint32 value) {
union {float f; uint32 i;};
i = value;
return f;
}
inline uint64 WireFormatLite::EncodeDouble(double value) {
union {double f; uint64 i;};
f = value;
return i;
}
inline double WireFormatLite::DecodeDouble(uint64 value) {
union {double f; uint64 i;};
i = value;
return f;
}
Run Code Online (Sandbox Code Playgroud)
现在,一个重要的附加信息是这些例程不是进程的结束,而是对它们的结果进行后处理,以便以小端顺序放置字节:
inline void WireFormatLite::WriteFloatNoTag(float value,
io::CodedOutputStream* output) {
output->WriteLittleEndian32(EncodeFloat(value));
}
inline void WireFormatLite::WriteDoubleNoTag(double value,
io::CodedOutputStream* …Run Code Online (Sandbox Code Playgroud) 在大多数情况下,我理解浮点比较测试应该使用一系列值(abs(xy)<epsilon)来实现,但自减法是否意味着结果为零?
// can the assertion be triggered?
float x = //?;
assert( x-x == 0 )
Run Code Online (Sandbox Code Playgroud)
我的猜测是nan/inf可能是特殊情况,但我对简单值发生的事情更感兴趣.
编辑:
如果有人可以引用参考(IEEE浮点标准),我很乐意选择答案吗?
在Javascript中将浮点数转换为二进制表示形式的最简单方法是什么?(例如1.0 - > 0x3F800000).
我试图手动完成,这在一定程度上(通常的数字)起作用,但是对于非常大或非常小的数字(没有范围检查)和特殊情况(NaN,无穷大等)都会失败:
function floatToNumber(flt)
{
var sign = (flt < 0) ? 1 : 0;
flt = Math.abs(flt);
var exponent = Math.floor(Math.log(flt) / Math.LN2);
var mantissa = flt / Math.pow(2, exponent);
return (sign << 31) | ((exponent + 127) << 23) | ((mantissa * Math.pow(2, 23)) & 0x7FFFFF);
}
Run Code Online (Sandbox Code Playgroud)
我重新发明轮子了吗?
编辑:我改进了我的版本,现在它处理特殊情况.
function assembleFloat(sign, exponent, mantissa)
{
return (sign << 31) | (exponent << 23) | (mantissa);
}
function floatToNumber(flt)
{
if (isNaN(flt)) // Special case: NaN
return …Run Code Online (Sandbox Code Playgroud) 我有一些单精度和双精度浮点数,我想写入并从字节[]中读取..Net中有什么东西可以用来将它们转换成32位和64位IEEE 754表示形式吗?
有什么办法可以在JS中读取浮点值的字节吗?我需要的是将原始FLOAT或DOUBLE值写入我需要制作的二进制格式,那么有没有办法获得逐字节的IEEE 754表示?当然,同样的写作问题.
对关键容器的键类型(例如std :: map)的比较器的要求是它对键类型的元素施加严格的弱顺序.
对于给定的比较器,comp(x, y)我们定义equiv(x, y) = !comp(x, y) && !comp(y, x).严格弱势秩序
的要求comp(x, y)是
!comp(x, x)适合所有人x)comp(a, b)和comp(b, c)再comp(a, c)).equiv(a, b)和equiv(b, c)然后equiv(a, c))std::less<float>(默认比较器)使用operator<,因为没有创建严格的弱顺序NaN.由于x < NaN和NaN < x是全是假的x,NaN就相当于这个比较下的所有花车,这打破条件#3:equiv(1.0, NaN)和equiv(NaN, 2.0),但不会equiv(1.0, 2.0).对于除NaN之外的IEEE浮点数,它是一个严格的弱顺序(其中每个数字都有自己的等价类,除了0和-0).
这是否意味着C++标准不允许使用IEEE浮点数(和(长)双精度数)作为关联容器中的键类型,因为上述问题,即使我确保NaN永远不会插入到容器中?我不太确定 …
考虑以下C++代码:
double someZero = 0;
std::cout << 0 - someZero << '\n'; // prints 0
std::cout << -someZero << std::endl; // prints -0
Run Code Online (Sandbox Code Playgroud)
问题出现了:什么是负零好处,应该是防御性的避免(即使用减法而不是减去变量)?
有谁知道包含浮点计算的C程序的随机生成器?
我正在寻找一些有点像Csmith的东西,除了Csmith不会生成浮点表达式,并且它会产生大量其他构造,使得修改有点困难.生成顺序计算对我来说是一个良好的开端,只要这些包括一些浮点数.条件会更好,但我不需要循环,指针,甚至数组.
由于这么多语言使用类C语法,这样的生成器可能不必特定于C.即使它特定于另一种类C语言,我也许能够将生成的语言文本处理为C程序.
编辑:这是一个Csmith生成的程序的片段,以澄清我在寻找什么.
...
int64_t *l_374 = &g_189;
int32_t l_375 = (-1L);
int i, j, k;
l_375 &= ((g_106 == ((*l_374) = (&g_324[4] == l_373[0][0][5]))) < 0x80C8L);
return (*g_207);
...
Run Code Online (Sandbox Code Playgroud)
我也应该澄清的是,虽然采取了输入csmith程序而代,比方说,int64_t
与float可以给一个语法正确的C程序,它几乎肯定不会给一个定义的程序.我可以测试替换程序是否包含未定义的行为,但这并不便宜,如果我必须拒绝99%的替换程序,因为它们未定义,过程将太慢而无法使用.
我试图围绕这个二进制数字的浮点表示,但我无法找到,无论我在哪里,都能找到一个很好的答案.
为什么指数有偏差?
旧的可靠的二次补码方法有什么问题?
我试着看一下维基百科关于这个主题的文章,但它所说的一切都是:"对于签名值的通常表示,会使比较变得更难."