Использование C: Как я могу определить размеры компонентов с плавающей запятой? - PullRequest
2 голосов
/ 02 ноября 2008

Я ищу предложения о том, как найти размеры (в битах) и диапазон чисел с плавающей запятой независимо от архитектуры. Код может быть построен на различных платформах (AIX, Linux, HPUX, VMS, возможно Windoze) с использованием разных флагов - поэтому результаты должны отличаться. Знак, который я видел только как один бит, но как измерить размер экспоненты и мантиссы?

Ответы [ 5 ]

5 голосов
/ 02 ноября 2008

Поскольку вы рассматриваете возможность создания ряда систем, я думаю, что вы, возможно, рассматриваете возможность использования GCC для компиляции.

Немного полезной информации о плавающей точке - это то, что используют почти все современные архитектуры: http://en.wikipedia.org/wiki/IEEE_754

Здесь подробно описаны некоторые различия, которые могут возникнуть http://www.network -theory.co.uk / Docs / gccintro / gccintro_70.html

3 голосов
/ 02 ноября 2008

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

3 голосов
/ 02 ноября 2008

Посмотрите значения, определенные в float.h. Они должны дать вам нужные вам значения.

2 голосов
/ 22 февраля 2009

Его относительно легко узнать:

Десятичный или двоичный код;

myfloat a = 2.0,
        b = 0.0;

for (int i=0; i<20; i++)
  b += 0.1;

(a == b) => decimal, else binary

Причина: все двоичные системы могут представлять 2.0, но любая двоичная система будет иметь срок ошибки для представления 0,1. Накапливая, вы можете быть уверены, что эта ошибка не исчезнет, ​​как при округлении: например, 1,0 == 3,0 * (1,0 / 3,0) даже в двоичных системах

Длина мантиссы:

Myfloat a = 1.0,
        b = 1.0,
        c,
        inc = 1.0;

int mantissabits = 0;

do {
 mantissabits++;
 inc *= 0.5;   // effectively shift to the right
 c = b+inc;
} while (a != c);

Вы добавляете убывающие условия, пока не достигнете способности мантиссы. Он возвращает 24 бита для числа с плавающей запятой и 53 бита для двойного числа, что является правильным (сама мантисса содержит только 23/52 бита, но поскольку первый бит всегда равен единице для нормализованных значений, у вас есть скрытый дополнительный бит).

Длина экспоненты:

Myfloat a = 1.0;
int max = 0,
    min = 0;

while (true) {
 a *= 2.0;
 if (a != NaN && a != Infinity && whatever) // depends on system
   max++;
 else
   break;
}

a = 1.0;
while (true) {
 a *= 0.5;
 if (a != 0.0) 
   min--;
 else
   break;
}

Вы сдвигаете 1,0 влево или вправо, пока не достигнете вершины или низа. Обычно диапазон опыта составляет -(max+1) - max.

Если min меньше, чем -(max+1), у вас есть (как у чисел с плавающей точкой, так и у двойных) субнормалы. Обычно положительные и отрицательные значения симметричны (возможно, с одним смещением), но вы можете настроить тест, добавив отрицательные значения.

1 голос
/ 02 ноября 2008

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

                      Sign      Exponent    Fraction    Bias
Single Precision    1 [31]     8 [30-23]      23 [22-00]         127
Double Precision    1 [63]    11 [62-52]      52 [51-00]        1023

РЕДАКТИРОВАТЬ: Как отметил Джонатан в комментариях, я пропустил тип long double . Я оставлю его битовую декомпозицию в качестве упражнения для читателя. :)

...