Pevent undefined behavior of ESMry scale factors for values <=0.
We use log10 of the value to compute the scale factor. This only makes sense for positive values. For zero it returns -HUGE_VAL and for negative values it returns nan where supported. Unfortunately on some platforms (e.g. mips64el) further operations in nan resulted in values so large that the scale factors were to large for the columns. This resulted in invalid_argument exceptions in strtod which were hard to debug. Out of pure luck on many platforms the scale factors still were zero in this case. To fix this we now always use a scale factor 0 for values less or equal to zero. This fixes e.g. Debian packages on mips64el. In addition we now make sure that printed scale factors have less characters than the column width. Otherwise parsing the *.RSM file might fail because of throwing strtod function.
This commit is contained in:
@@ -186,7 +186,15 @@ void ESmry::write_block(std::ostream& os,
|
||||
const auto& vector_data { this->get(vector) } ;
|
||||
|
||||
auto max = *std::max_element(vector_data.begin(), vector_data.end());
|
||||
int scale_factor { std::max(0, 3 * static_cast<int>(std::floor(( std::log10(max) - 4 ) / 3 ))) } ;
|
||||
// log10 for 0 is undefined and log10 for negative values yields nan.
|
||||
// We skip the scale factor in these cases to prevent undefined behavior
|
||||
int scale_factor {
|
||||
max <= 0 ? 0 :
|
||||
std::max(0, 3 * static_cast<int>(std::floor(( std::log10(max) - 4 ) / 3 ))) } ;
|
||||
|
||||
// Make sure that 10**scale_factor is less than 13 character
|
||||
scale_factor = std::min(99999999, scale_factor);
|
||||
|
||||
if (scale_factor) {
|
||||
has_scale_factors = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user