Возврат значения экспоненты числа с плавающей запятой

Как я могу вернуть только экспоненциальную часть числа с плавающей запятой? Это одинарная точность, поэтому мне нужно получить значение восьми битов экспоненты.

int floatExp(float f) { 
 //Return the exponent value for f. return tmax if f is nan or infinity
}

person donth77    schedule 03.03.2014    source источник
comment
Вы ищете frexp? (frexpf для поплавка)   -  person torek    schedule 03.03.2014


Ответы (3)


Стандартный способ извлечь двоичную экспоненту — использовать функцию frexp() из math.h. См. http://www.csse.uwa.edu.au/programming/ansic-library.html#float

Если вам нужен десятичный показатель степени, используйте функцию log10() в math.h.

person Raymond Hettinger    schedule 03.03.2014
comment
Или используйте в качестве дешевой и почти точной замены log10 значение (frexp(x,&m)*3)/10 - person Lutz Lehmann; 04.03.2014

Код, безусловно, должен передавать float, а не unsigned.

// int floatExp(unsigned f)
int floatExp(float f)

Используйте isfinite и frexpf().

#include <math.h>
int floatExp2(float value) {
  int exp;
  if (isfinite(value)) {
    frexpf(&exp);
    return exp;
  }
  return tmax;
}

Для основания 10 немного больше работы.

#include <math.h>
int floatExp10_(float value) {
  if (isfinite(value)) {
    if (value == 0.0) return 0;
    float exp = log10f(fabsf(value));

    // use floorf() rather than `(int) exp`.  
    // This does the proper rounding when `exp` is + or -
    return (int) floorf(exp);
  }
  return tmax;
}

C не определяет, что числа с плавающей запятой и float имеют "восемь битов экспоненты". Он также не определяет, что показатель степени является двоичным. Во многих реализациях используется двоичный формат с плавающей запятой одинарной точности IEEE 754: binary32, который имеет 8-битная экспонента со смещением степени 2.

Хак-способ - использовать союз. Этот непереносимый метод сильно зависит от знания формата с плавающей запятой, размера целого числа, порядка байтов числа с плавающей запятой и целого числа. Следующее или его вариант может работать в среде OP.

int floatExp_hack(float value) {
  if (isfinite(value)) {
    union {
      float f;
      value unsigned long ul;
    } u;
    assert(sizeof u.f == sizeof u.ul);
    u.f = value;
    return (u.ul >> 23) & 0xFF;
  }
  return tmax;
}
person chux - Reinstate Monica    schedule 03.03.2014

Возьмите журнал в любой базе, в которой вы хотите получить показатель степени.

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

person Thanatos    schedule 03.03.2014