根据普朗克定律,我一直致力于实施黑体辐射:
double BlackBody(double T, double wavelength) {
wavelength /= 1e9; // pre-scale wavelength to meters
static const double h = 6.62606957e-34; // Planck constant
static const double c = 299792458.0; // speed of light in vacuum
static const double k = 1.3806488e-23; // Boltzmann constant
double exparg = h*c / (k*wavelength*T);
double exppart = std::exp(exparg) - 1.0;
double constpart = (2.0*h*c*c);
double powpart = pow(wavelength, -5.0);
double v = constpart * powpart / exppart;
return v;
}
我有一个float [max-min + 1]数组,其中static const int max = 780,static const int min = 380.我只是迭代数组,然后输入BlackBody给出的波长(波长) = array-index + min)。 IntensitySpectrum :: BlackBody执行此迭代,而min和max都是静态成员变量,并且数组也在IntensitySpectrum中。
IntensitySpectrum spectrum;
Vec3 rgb = spectrum.ToRGB();
rgb /= std::max(rgb.x, std::max(rgb.y, rgb.z));
for (int xc = 0; xc < grapher.GetWidth(); xc++) {
if (xc % 10 == 0) {
spectrum.BlackBody(200.f + xc * 200.f);
spectrum.Scale(1.0f / 1e+14f);
rgb = spectrum.ToRGB();
rgb /= std::max(rgb.x, std::max(rgb.y, rgb.z));
}
for (int yc = 20; yc < 40; yc++) {
grapher(xc, yc) = grapher.FloatToUint(rgb.x, rgb.y, rgb.z);
}
}
问题在于,line谱.BlackBody()将数组的第0个元素设置为NaN,而只将第0个元素设置为NaN。此外,第一次迭代也不会发生,但是xc&gt; = 10以下的所有迭代都会发生。
VS调试器中的文本: spectrum = {intensity = 0x009bec50 {-1。#IND0000,520718784。,537559104.,554832896。,572547904。,590712128.,609333504。,...}}
我跟踪了错误,并且:: BlackBody()函数中的exppart变为NaN,基本上exp()返回NaN,即使它的参数接近2.0,所以definetely不会溢出。但仅适用于数组索引0.它神奇地开始为其余400个索引工作。
我知道记忆超支可能会导致类似的事情发生。这就是为什么我仔细检查了我的记忆处理。 我将Vec3与另一个自制的库连接起来,这个库要大得多,可能包含错误,但我从Vec3使用的内容与内存无关。
几个小时后,我完全无能为力。还有什么可以导致这个?是优化器还是WINAPI欺骗我......? (嗯,是的,程序用WINAPI创建一个窗口,并使用几乎空的WndProc来调用WM_PAINT上的代码。)
先谢谢你的帮助。
很抱歉让它不清楚。这是布局:
// member
class IntensitySpectrum {
public:
void BlackBody(float temperature) {
// ...
this->intensity[i] = ::BlackBody(temperature, wavelength(i));
// ...
}
private:
static const int min = 380;
static const int max = 780;
float intensity[max-min+1];
}
// global
double BlackBody(double T, double wavelength);
答案 0 :(得分:1)
如果您碰巧使用MSVC 2013,可能的一种解释是您在某处尝试将浮点无穷大转换为int。当发生这种情况时,MSVC 2013中的错误会导致x87 FPU堆栈上的不平衡推送。触发该错误8次并且您的FPU堆栈完全填满,并且任何后续尝试推送值(例如调用'exp()')将导致'无效操作'并返回无限期(如1.#IND) 。请注意,即使您使用SSE2浮点指令进行编译,此错误仍然可以咬人,因为调用约定规定在FPU堆栈顶部返回浮点返回值。
要检查这是否是您的问题,请在错误调用'exp()'之前查看您的FPU寄存器。如果您的TAGS寄存器全为零,那么您的FPU堆栈已满。
MS声称这将在MSVC 2013的更新2中修复。
答案 1 :(得分:-1)
以下函数调用只有1个参数:
spectrum.BlackBody(200.f + xc * 200.f);
因此无法调用您定义为
的函数double BlackBody(double T, double wavelength)
如果你看一下::BlackBody
实现,我打赌你在某个地方有0分之差。