Недавно я столкнулся с проблемой, что visual-c++
не соответствует IEEE 754, но вместо этого использует субнормальное представление. То есть числа с плавающей запятой двойной точности в нем не имеют обычного представления из 1 знакового бита, 11 битов экспоненты и 52 явно сохраненных значащих десятичных битов, см. ниже.
Однако, поскольку gcc
и clang
совместимы, а единообразное межплатформенное поведение крайне желательно, я хотел бы знать, можно ли заставить visual-c++
использовать нормальное представление. В качестве альтернативы использование gcc
и clang
субнормального представления, конечно, также решит проблему.
Проблема различных двойных представлений может быть воспроизведена в visual-c++
, gcc
и clang
, используя следующий код:
#include <iostream>
#include <string>
int main()
{
try {
std::stod("8.0975711886543594e-324");
std::cout << "Subnormal representation.";
} catch (std::exception& e) {
std::cout << "Normal representation.";
}
return 0;
}
Возможна ли вообще спецификация представления для создания согласованного поведения во всех трех случаях?
Изменить: Как указал geza, это проблема в различных реализациях std::stod
, что затем вызовет вопрос, есть ли способ заставить std::stod
вести себя последовательно, без необходимости реализовывать для него отдельную оболочку.
std::stod
, не так ли? GCC и clang выбрасывают out_of_range для субнормальных чисел (что странно, если вы спросите меня), а msvc — нет. Я даже не понимаю, почему они выбрасывают out_of_range для небольшого числа, которое обрезается до нуля. Это определенно не out_of_range. Для этого случая должно быть отдельное исключение. - person geza   schedule 19.11.2018std::stod
плохо спроектирован.strtod
может сообщить, означает ли ERANGE переполнение или недополнение.std::stod
не может. - person geza   schedule 19.11.2018std::stod
, может быть, есть какой-то стандартный способ обойти дизайн. - person abcalphabet   schedule 19.11.2018strtod
, у которого нет этого ограничения. Он ведет себя не так, как задокументировано для субнормальных чисел: он возвращает субнормальное значение (поэтому, вопреки документу, он возвращает ненулевое значение, но устанавливает errno=ERANGE). Что хорошо для нас, потому что вы можете получить номер, который вы хотите. - person geza   schedule 19.11.2018std::strtod(cstr, nullptr)
, спасибо! Если вы хотите превратить это в ответ, я был бы рад принять его - person abcalphabet   schedule 19.11.2018