Сколько представляемых поплавков существует между 0.0
и 0.5
? И сколько представимых поплавков существует между 0.5
и 1.0
? Меня больше интересует математика за этим, и мне нужен ответ за floats
и doubles
.Сколько различных чисел с плавающей запятой в определенном диапазоне?
ответ
Для IEEE754 плавает, это довольно прямо вперед. Запустите Online Float Calculator и продолжайте читать.
Все чистые силы 2 представлены мантиссы 0
, которая на самом деле 1.0
из-за подразумеваемый ведущей 1. Показатель корректируется с помощью смещения, так что 1 и 0,5 соответственно 1,0 × и 1,0 × , или в двоичной системе:
S Ex + 127 Mantissa - 1 Hex
1: 0 01111111 00000000000000000000000 0x3F800000
+ 0 + 127 1.0
0.5: 0 01111110 00000000000000000000000 0x3F000000
+ -1 + 127 1.0
Так как числа с плавающей точкой, представленных в этой форме упорядочены в том же Orde r как их двоичное представление, нам нужно только разделить интегральное значение двоичного представления и заключить, что существуют 0x800000 = , т.е. 8388 608 значений с плавающей точкой с одной точностью в интервале [0,5, 1,0).
Аналогично, ответ 2 для double
и 2 для long double
.
... и есть «0x3F000000» представимые одноточечные поплавки между «0.0» и «0.5», что составляет более 1 миллиарда. Ницца! – Arlen
Для 0.0..0.5: вам нужно беспокоиться об экспонентах от -1 до минимума, а затем умножить, сколько вы получите время, количество различных значений, которые вы можете представить в мантиссе.
Для каждого значения в этом диапазоне, если вы удвоите его, вы получите значение в диапазоне 0.5..1.0. И удвоение означает просто нагнетание экспоненты.
Вам также нужно беспокоиться о ненормализованных числах, где мантисса не используется для представления 1.x, но 0.x, и, следовательно, все будет в вашем нижнем диапазоне, но не может быть удвоена, экспонента (поскольку конкретное значение показателя используется для указания того, что значение ненормировано).
«Для каждого значения в этом диапазоне, если вы дважды, вы получите значение в диапазоне 0.5..1.0. " eh no вам нужно * добавить * 0.5, что означает, что все числа ниже 'ulp (0.5)' все будут одинаковыми (0.5), для диапазона 0.5..1 все показатели равны -1 –
К сожалению, я думал о он в другом направлении (идет от диапазона 0.5..1.0 и сокращает вдвое все, что БУДЕТ все карты в нижний диапазон). –
да, но у него не было бы ВСЕ чисел, особенно тех, которые <0.25 –
Это не ответ, но вы можете получить какой-то недостаток из функции nextafter
. Нечто подобное должно помочь вам ответить на ваш вопрос, но вы должны будете отработать математику себя:
float f = 0;
while(f < 0.5)
{
print("%f (repr: 0x%x)\n", f, *(unsigned *)&f);
f = nextafterf(f, 0.5);
}
, прежде чем вы начнете эту попытку ** половина ** представляемых чисел в плавающей запятой между -1 и 1 для float, которая составляет 2 миллиарда (или 1 миллиард от 0 до 1), для двойного числа, которое это число * квадратично *, если вы начинаете считать, что вы будете ждать некоторое время –
@ratchetfreak - Правда, но если вы не знаете основную математику (например, я), вы можете начать собирать образец с первых 20 максимум, а затем все, что вы действительно нужно знать, это начальная и конечная точки. Но да, лучше, если вы знаете математику за ней. –
Число с плавающей запятой в формате IEEE754 составляет от 0,0 (включительно) до 0,5 (исключая) тогда и только тогда, когда знаковый бит равен 0, а показатель - < -1
. Биты мантиссы могут быть произвольными. Для float
, что составляет 2^23
номеров на допустимый показатель, для double
2^52. Сколько допустимых экспонентов существует?Для float
, минимальный показатель для нормализованных чисел -126, для double
это -1022, так что есть
126*2^23 = 1056964608
float
значение в [0, 0.5)
и
1022*2^52 = 4602678819172646912
double
значение.
Kerrek дал лучшее объяснение :)
Только в случае здесь код, чтобы играть с другими интервалами тоже
http://coliru.stacked-crooked.com/a/7a75ba5eceb49f84
#include <iostream>
#include <cmath>
template<typename T>
unsigned long long int floatCount(T a, T b)
{
if (a > b)
return 0;
if (a == b)
return 1;
unsigned long long int count = 1;
while(a < b) {
a = std::nextafter(a, b);
++count;
}
return count;
}
int main()
{
std::cout << "number of floats in [0.5..1.0] interval are " << floatCount(0.5f, 1.0f);
}
печатает
number of floats in [0.5..1.0] interval are 8388609
подсказка: сколько бит используются для представления этого дробного диапазона? –
Я не помню доказательство, но вы можете найти ответ в http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html или http: // с плавающей запятой .de /. – Crashworks
не забудьте посчитать -0.0 :-) – franji1