Вопрос

Я хочу найти количество цифр мантиссы и округление единицы измерения на конкретном компьютере.У меня есть представление о том, что это такое, просто я понятия не имею, как их найти - хотя я понимаю, что они могут варьироваться от компьютера к компьютеру.

Мне нужно это число для того, чтобы выполнить определенные аспекты численного анализа, например, проанализировать ошибки.

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

Нахожусь ли я на правильном пути?Как именно можно это рассчитать?

Это было полезно?

Решение

Я бы подумал, что какой бы язык вы ни использовали, он указывал бы, как хранятся значения с плавающей точкой.Я знаю, что Java делает это с помощью определенного стандарта IEEE (754, я думаю).

Если это не указано, я бы подумал, что вы могли бы просто выполнить свою собственную проверку, добавив 0,5 к 1, чтобы увидеть, изменится ли фактическое число.Если это так, то добавьте 0,25 к 1, 0,125 к 1 и так далее, пока число не изменится, что-то вроде:

float a = 1;
float b = 0.5;
int bits = 0;
while (a + b != a) {
    bits = bits + 1;
    b = b / 2;
}

Если бы у вас было только 3 бита мантиссы, то 1 + 1/16 было бы равно 1.

Тогда вы исчерпали свои кусочки мантиссы.

Возможно, вам действительно нужно, чтобы базовое число было 2, а не 1, поскольку IEEE754 использует подразумеваемое '1 +' в начале.

Редактировать:

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

Связано ли это с промежуточными результатами (я сомневаюсь в этом, поскольку тот же код с явными приведениями [while (((float)(a + b) != (float)(a))] имеет аналогичные проблемы) или (что более вероятно, я полагаю) возможность того, что единичное значение a может быть представлен битами, более близкими к дробному b регулируя показатель степени, я пока не знаю.

На данный момент лучше всего полагаться на информацию о языке, которую я упомянул выше, такую как использование IEEE754 (если эта информация доступна).

Я оставлю проблемный код в качестве ловушки для осторожных игроков.Может быть, у кого-то больше знаний о плавающей запятой, тогда я смогу оставить записку, объясняющую, почему это действует странно (никаких предположений, пожалуйста:-).

ПРАВКА 2:

Этот фрагмент кода исправляет это, гарантируя, что промежуточные элементы хранятся в floats .Оказывается, Джонатан Леффлер был прав - это были промежуточные результаты.

#include <stdio.h>
#include <float.h>

int main(void) {
    float a = 1;
    float b = 0.5;
    float c = a + b;
    int bits = 1;
    while (c != a) {
        bits = bits + 1;
        b = b / 2;
        c = a + b;
    }
    printf("%d\n",FLT_MANT_DIG);
    printf("%d\n",bits);
    return 0;

}

Этот код выводит (24,24), чтобы показать, что вычисленное значение соответствует значению в заголовочном файле.

Хотя он написан на C, он должен быть применим к любому языку (в частности, к тому, где информация недоступна в заголовке или в силу того, что она указана в языковой документации).Я тестировал только на C, потому что Eclipse так долго запускается на моем компьютере Ubuntu :-).

Другие советы

Для C и, расширяя C ++, информация находится в <float.h> или <cfloat> заголовки.

Для C99 информация приведена в разделе 5.2.4.2.2 стандарта:

  • FLT_RADIX
  • FLT_MANT_DIG
  • FLT_DIG
  • FLT_EPSILON
  • FLT_MIN_EXP
  • FLT_MIN
  • FLT_MIN_10_EXP
  • FLT_MAX_EXP
  • FLT_MAX
  • FLT_MAX_10_EXP

И аналогично для вариаций DBL и LDBL для большинства из них (нет DBL_RADIX или LDBL_RADIX).Стандарт предлагает значения, соответствующие стандарту IEEE 754 (более старая версия стандарта IEEE 754 , действовавшая в 1999 году;была новая версия, опубликованная, по-моему, в 2008 году).

Возможно, вы захотите проверить <limits> в вашей библиотеке C ++:

#include <iostream>
#include <limits>
#include <typeinfo>

template <typename T>
void printDetailsFor() {
    std::cout
        << "Printing details for " << typeid(T).name() << ":\n"
        << "\tradix:        " << std::numeric_limits<T>::radix        << "\n"
        << "\tradix digits: " << std::numeric_limits<T>::digits       << "\n"
        << "\tepsilon:      " << std::numeric_limits<T>::epsilon()    << "\n"
        << std::endl;
}

int main() {
    printDetailsFor<int>();
    printDetailsFor<float>();
    printDetailsFor<double>();
    printDetailsFor<long double>();
    return 0;
}

Я думаю, что ты хочешь std::numeric_limits<T>::digits что должно быть на единицу больше, чем количество битов мантиссы.Моя машина распечатывает:

Printing details for i:
    radix:        2
    radix digits: 31
    epsilon:      0

Printing details for f:
    radix:        2
    radix digits: 24
    epsilon:      1.19209e-07

Printing details for d:
    radix:        2
    radix digits: 53
    epsilon:      2.22045e-16

Printing details for e:
    radix:        2
    radix digits: 64
    epsilon:      1.0842e-19
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top