Создание значения с плавающей запятой NaN из частей знака, экспоненты и мантиссы в С++

Мне нужно создать переменную с плавающей запятой в C++, которая имеет значение NaN. Мне также нужно иметь возможность видеть, какой NaN имеет большее значение. Чтобы сравнить NaN, вам нужно посмотреть на часть мантиссы поплавка. Создание NaN с использованием стандарта

nanf("abc"); 

Метод приводит к NaN с одной и той же мантиссом, даже если в функции nanf используются разные строки. Создание NaN из основных частей битового шаблона должно обеспечить разные мантиссы, и поэтому можно выполнить простую сортировку по размеру мантиссы.


person thorphar111    schedule 07.02.2016    source источник
comment
Добро пожаловать на stackoverflow.com. Пожалуйста, найдите время, чтобы прочитать страницы справки, особенно разделы с именами На какие темы я могу задать здесь? и Какие типы вопросов мне следует избегать? . Также, пожалуйста, прочитайте о том, как задавать хорошие вопросы. Вы также можете узнать, как создать минимальный, полный и проверяемый пример.   -  person Some programmer dude    schedule 07.02.2016
comment
Вы пробовали десятичные строки вместо acb? Или вы можете создать требуемый битовый шаблон самостоятельно. Поскольку большинство реализаций это делают, может быть приемлемым ограничить код, который вы пишете, реализациями, использующими числа с плавающей запятой IEEE. Просто поместите нужный шаблон в переменную uint32_t и memcpy в переменную float.   -  person Paul Groke    schedule 07.02.2016
comment
nanf определяется реализацией, поэтому ответ зависит от вашей реализации. Какой компилятор вы используете?   -  person Alan Stokes    schedule 07.02.2016
comment
Я использую Visual Studio для компиляции. Обычно я использую g++, но я получаю так много ошибок, что их легче отлаживать в VS. Я попробую это в g++ и посмотрю, что он вернет. Это может решить мою проблему.   -  person thorphar111    schedule 07.02.2016
comment
Похоже, вам не повезло с MSVC: входное значение игнорируется msdn. microsoft.com/en-us/library/dn465173.aspx   -  person Alan Stokes    schedule 07.02.2016
comment
Возможный дубликат stackoverflow .com/questions/14033267/   -  person Alan Stokes    schedule 07.02.2016


Ответы (2)


Взгляните на семейство функций frexp(), а также на ldexp(), которое немного противоположно frexp().

Ссылка: http://www.cplusplus.com/reference/cmath/ldexp/

person Severin Pappadeux    schedule 07.02.2016
comment
К сожалению, вы не можете создать NaN таким образом. - person Alan Stokes; 07.02.2016

Вот пример значений с плавающей запятой с каламбуром с объединениями и целочисленными битовыми полями.

#include <iostream>

union floatPun {
    struct {
        unsigned int mantissa : 23;
        unsigned int exponent : 8;
        unsigned int sign     : 1;
    };
    float value;
};

union doublePun {
    struct {
        unsigned long long mantissa : 52;
        unsigned long long exponent : 11;
        unsigned long long sign     : 1;
    };
    float value;
};

template <typename PunT>
static int compare_mantissas(const PunT& a, const PunT& b) {
    return int(a.mantissa > b.mantissa) - (b.mantissa > a.mantissa);
}

int main() {
    floatPun fa = {0}, fb = {0};

    // make NaNs
    fa.exponent = fb.exponent = 0xff;
    fa.mantissa = 1;
    fb.mantissa = 2;
    std::cout << "fa: " << fa.value << "   fb: " << fb.value << "\n";

    // compare mantissas
    static const char* const cmp_labels[] = {"less than", "equal to", "greater than"}; 
    std::cout << "mantissa of fa is " 
        << cmp_labels[1 + compare_mantissas(fa, fb)]
        << " mantissa of fb\n";

    // change fa to +infinity
    fa.mantissa = 0;
    std::cout << "changed fa's mantissa to zero: " << fa.value << "\n";
}
person Christopher Oicles    schedule 07.02.2016