我一直致力于根据普朗克定律实施黑体辐射,具体如下:
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-指数 + 分钟)。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);
}
}
问题在于,线谱.BlackBody() 将数组的第 0 个元素设置为 NaN,并且只有第 0 个元素。此外,它不会发生在第一次迭代中,而是发生在 xc>=10 的所有以下迭代中。
来自 VS 调试器的文本:频谱 = {intensity=0x009bec50 {-1.#IND0000, 520718784., 537559104., 554832896., 572547904., 590712128., 609333504., ...} }
我跟踪错误, ::BlackBody() 函数中的 exppart 变为 NaN,基本上 exp() 返回 NaN,即使它的参数接近 2.0,所以绝对不会溢出。但仅适用于数组索引 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);