Я работал над реализацией излучения черного тела в соответствии с законом Планка с нижеследующим:двойной ехр (двойной) неожиданно возвращается NaN (нет переполнения с плавающей точкой)
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;
}
У меня есть поплавок [максиминимального +1], где static const int max = 780, static const int min = 380. Я просто перебираю массив и добавляю то, что BlackBody дает для длины волны (длина волны = индекс массива + мин). 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);
}
}
Проблема заключается в том, что линия spectrum.BlackBody() устанавливает 0-й элемент массива к NaN, и только 0th. Также это не происходит для самой первой итерации, но все следующие, где xc> = 10.
текст из VS отладчик: {. Интенсивность = 0x009bec50 {-1 # IND0000, 520718784., 537559104., 554832896., 572547904., 590712128., 609333504., ...}} спектра =
Я отслеживал ошибку вниз, а функция part :: blackBody() становится NaN, в основном exp() возвращает NaN, хотя аргумент равен около 2.0, поэтому определенно не переполняется. Но только для индекса массива 0. Он волшебным образом начинает работать для остальных 400 индексов.
Я знаю, что перерасход памяти может привести к подобным вещам. Вот почему я дважды проверил работу с памятью. Я связываю Vec3 с другой самодельной библиотекой, которая намного больше и может содержать ошибки, но то, что я использую из Vec3, не имеет ничего общего с памятью.
После многих часов я совершенно не знаю. Что еще может вызвать это? Оптимизатор или WINAPI обманывают меня ...? (Uhm, да, программа создает окно с 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);
Вы показали 'двойной чернотельный (двойной T, двойной длины волны)', который, по-видимому, не то, что вы вызывают в другом блоке кода. Там вы вызываете 'IntensitySpectrum :: BlackBody (float)' или 'IntensitySpectrum :: BlackBody (double)'. Второго аргумента нет, и вы не используете возвращаемое значение из этого вызова функции. –