未初始化的浮点变量,再现不确定的行为
Uninitialized floating point variables, repoducing indeterminate behavior
我必须调试一些显示瞬时和零星行为的代码,这最终可能归因于初始化行中未初始化的float,即:
float a = number, b, c = other_number;
这段代码通过串行连接快速采样设备,并在一定间隔内平均输出。每隔一段时间,会报告数字2.7916085e+035,但否则代码按预期工作,并且错误不可重现。
由于数字总是2.7916085e+035,我认为可能有一些问题与通信处理,或设备本身,但这些被排除。我几乎准备把它归咎于外部干扰,直到我终于在调试器中发现了一个错误的样本。
那么,回答这个问题。有人可以假设2.7916085e+035的意义吗?我不确定它在我的语境之外有什么意义,但让我困扰的是这个数字本质上是不可复制的可复制的。也就是说,我不能可靠地复制这个问题,但当它出现时,它总是一样的。从我的理解,未初始化的变量应该是不确定的。值得注意的是,问题发生在程序执行的所有不同位置、阶段、时间等。但总是在同一个系统上。
是。net框架、运行时或操作系统中的某些东西导致了这种行为吗?这是特别麻烦的跟踪,因为未初始化的变量总是具有相同的值,当它没有被幸运地设置为0时。
编辑:一些上下文。代码位于计时器内,计时器具有可变的滴答率,因此变量是类的局部非静态成员:
if(//some box checked)
{
switch(//some output index)
{
case problem_variable:
{
if(ready_to_sample)
{
float average;
for each(float num in readings)
{
average += num;
}
average /= readings.Count;
}
}
}
}
这里的变量是average
。readings
是我想求平均值的输出列表。average
将在每个....中重新声明一次平均值,可以以秒、分、小时或任何满足取平均值条件的时间为单位。该变量通常会得到0,但偶尔也会得到上面的数字。
在常见的浮点编码中,2.7916085e+035是0x7a570ec5作为浮点数,0x474ae1d8a58be975作为双精度,模端序。它们看起来不像典型的文本字符串、简单整数或普通地址。(双位数编码的低位是不确定的,因为你没有捕获足够的十进制数字来确定它们,但是高位看起来没有意义。)
64位二进制中的double转换成
0100011101001010111000011101100010100101100010111110100000000000
或
01111010010101110000111011000101
为32位浮点数。几乎所有现代处理器都将指令和数据分开——尤其是R/W数据。当然,旧的x86是例外,它是一种CISC处理器,基于4004处理器,那时每个字节都很宝贵,甚至小型计算机也没有缓存可以使用。然而,在现代操作系统中,更有可能的情况是,在移动4或8KB的页面时,更改了一页指令,而没有将旧页面清零。
双版本可能相当于
Increment by 1, where r7 (EDI - extended destination index) is selected
第二个,作为浮点数,看起来它可以转换为x86或x86-64:
我如何解释这个x86_64汇编操作码?
您看到的未初始化变量的值是该内存位置中发生的任何值。这不是随机的;它是一个由之前的函数调用存储在内存中的值。例如:
void f() {
int i = 3;
}
void g() {
int i;
std::cout << i << std::endl;
}
int main() {
f();
g();
return 0;
}
很有可能,这个程序(假设编译器没有优化f()
中的初始化)将把3
写入控制台。
浮点数是以2为基数的数制。因此,有一些特定的值不能准确地保存,并计算为近似值。
您的输出可能会给您一个特定的得到相同估计的值。尝试运行从串行连接获得的一些常见值,看看是否能找到导致您悲伤的值。我个人会用双精度数来代替浮点数,特别是当你要对这些数字做任何计算的时候。
- 为什么我的 c++ 程序检查不是初始化的变量?
- "变量":函数中函数作用域不允许初始化的自动或寄存器变量'naked'
- 为什么std::atomic的默认构造函数不默认初始化底层存储值
- 数组不保存初始化值
- 为什么作为返回类型的右值引用不能初始化非常量引用?
- 程序告诉我初始化在编写简单的C ++代码时不需要初始化的变量
- IMFSinkWriter::BeginWriting 不会初始化,因为 IMFMediaEventGenerator
- OpenGL C++:VBO 的结构包装器不会初始化成员
- Visual Studio,找不到初始化术语,无法再调试
- C 错误变量大小对象可能不会初始化
- 为什么可以将Char指针变量初始化为字符串,而INT指针变量不能初始化到整数数组
- 使用C 中的Cython CDEF公共变量:变量永远不会初始化
- 为什么您可以初始化常量引用,但不能初始化来自右值的非常量引用
- 为什么我的变量被强制初始化为 0,即使它不应该初始化?
- C++将数组直接传递到函数中,而不首先初始化它
- 为什么在构造函数之外不允许初始化类成员
- 全局静态常量字符串不会初始化
- 为什么VS2013不零初始化此结构?
- auto_ptr构造函数主体(不在初始化器列表中)的成员初始化
- C++ 为什么我可以初始化静态常量字符,但不能初始化类定义中的静态常量双精度