AS>>>>Распределение вещественных чисел, представляемых флоат (да и любым числом с плавающей точкой) на множестве вещественных чисел, неравномерно. Наиболее плотно числа представлены (отбросив знак) в районе единицы, далее, ближе к границам диапазона — значительно более разрежено. Т.е. далеко не все целые числа из диапазона флоата можно с точностью до +-0.5 им представить. T>>>Наиболее плотно — в районе нуля
AS>>С чего это? Флоат хранится в нормализованом виде с неявной единицой. T>Спорить не буду. Но мне всегда казалось, что от -0.1 до 0.1 флоатов больше, чем от 0.9 до 1.1. Но если окажется, что это не так, то я не очень расстроюсь.
In order to maximize the quantity of representable numbers, floating-point numbers are typically stored in normalized form. This basically puts the radix point after the first non-zero digit. In normalized form, five is represented as 5.0 x 10^0.
A nice little optimization is available to us in base two, since the only possible non-zero digit is 1. Thus, we can just assume a leading digit of 1, and don't need to represent it explicitly. As a result, the mantissa has effectively 24 bits of resolution, by way of 23 fraction bits.
Putting it All Together
So, to sum up:
The sign bit is 0 for positive, 1 for negative.
The exponent's base is two.
The exponent field contains 127 plus the true exponent for single-precision, or 1023 plus the true exponent for double precision.
The first bit of the mantissa is typically assumed to be 1.f, where f is the field of fraction bits.
Здравствуйте, Andrew S, Вы писали:
T>>>А в качестве индекса все равно поиспользовать не получится... хоть double используй, хоть __int64.
LVV>>Предел float 10^38 = 2^38*5^38 LVV>>2^42 = 2^4*2^38 = 16*2^38 LVV>>Очень даже организуешь! LVV>>Или я где-то грабли не вижу?
AS>Конечно не видите, что, вообще говоря, странно...
Ничего странного С такими числами редко дело иметь приходится и в очередной раз забываешь, что компьютерные числа — это не математические. Всю эту теорию я сам знаю и студентам тож самое говорю про разреженность и плотность, но вот поди ж ты...
AS>Распределение вещественных чисел, представляемых флоат (да и любым числом с плавающей точкой) на множестве вещественных чисел, неравномерно. Наиболее плотно числа представлены (отбросив знак) в районе единицы, далее, ближе к границам диапазона — значительно более разрежено. Т.е. далеко не все целые числа из диапазона флоата можно с точностью до +-0.5 им представить. Более того. Общее количество (вещественных) чисел, представляемых float, составляет примерно (точно я не помню) 2^25 + 1. Общее количество (вещественных) чисел, представляемых double, состоявляет 2^53 + 1, т.е. им представить 42 битное число с некоторой осторожностью можно (при этом, очевидно, от операции инкремента в виде прибавления единички к значению придется отказаться, придумав нечто другое, что не изменяло бы значения порядка, а только мантиссы). В общем — правильнее и быстрее использовать вложеный цикл на long, если компилер не поддерживает 64-х битные целые.
В общем я проверил на следующей программе BCB6
int main(int argc, char* argv[])
{ for (double i = 4398046511000; i <4398046511103; i++)
{ cout << i << endl;
}
getch();
return 0;
}
Цикл вполне нормально завершается
Если вместо double стоит float, то даже в цикл не входит.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Andrew S, Вы писали:
AS>>>>>Распределение вещественных чисел, представляемых флоат (да и любым числом с плавающей точкой) на множестве вещественных чисел, неравномерно. Наиболее плотно числа представлены (отбросив знак) в районе единицы, далее, ближе к границам диапазона — значительно более разрежено. Т.е. далеко не все целые числа из диапазона флоата можно с точностью до +-0.5 им представить. T>>>>Наиболее плотно — в районе нуля
AS>>>С чего это? Флоат хранится в нормализованом виде с неявной единицой. T>>Спорить не буду. Но мне всегда казалось, что от -0.1 до 0.1 флоатов больше, чем от 0.9 до 1.1. Но если окажется, что это не так, то я не очень расстроюсь.
AS>Ну, значит вам таки надо будет хоть немного, но расстроиться AS>http://research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html
Спасибо за ссылку. Но наверное все-таки наибольшая плотность в районе нуля.
Приведу пример. Пусть есть два диапазона (положительных) флоатов. Первый представлен экспонентой =–126, второй =0. И в том и в другом умещается одинаковое (2^11) чисел. Примерные границы диапозонов: первый – с 2^-126 до 2^-125, второй с 1 до 2. Первый отрезок значительно короче и ближе к нулю (чем к единице).
PS.Прийти к неверному выводу о наибольшей плотности в районе единицы можно рассуждая примерно так. Чем больше экспонента, тем больше представимое число и тем более разреженно размещаются флоаты, значит максимум плотности в районе экспоненты = 0. Забывая при этом о ширине поддиапозонов при отрицательных значениях степени.
B>Спасибо за ссылку. Но наверное все-таки наибольшая плотность в районе нуля. B>Приведу пример. Пусть есть два диапазона (положительных) флоатов. Первый представлен экспонентой =–126, второй =0. И в том и в другом умещается одинаковое (2^11) чисел. Примерные границы диапозонов: первый – с 2^-126 до 2^-125, второй с 1 до 2. Первый отрезок значительно короче и ближе к нулю (чем к единице).
Да, вероятно вы правы. Я потом и сам об этом подумал.
Наибольшая плотность -- в районе нуля. Потому что количество плавающих чисел в диапазонах [2^d,2^(d+1)) одинаково. В частности, плавающих чисел на отрезке [1/2,2) столько же, сколько и на отрезке [1/4,1), или на [1/8,1/2) и.т.д. (За исключение совсем уж маленьких значений для экспоненты, конечно).
Здравствуйте, LaptevVV, Вы писали:
maq>> Если нет то можно реализовать с использованием двух 32-х битных L> А можно и адщфе использовать, если использовать в качестве индекса не L> нужно.
Категорически нельзя. В данном примере идеология плавающей точки гарантирует кучу геморроя при инкременте числа, вплоть до бесконечного цикла (при достаточно большой величине константы ZNACHENIE).
Здравствуйте, ArtDenis, Вы писали:
maq>>> Если нет то можно реализовать с использованием двух 32-х битных L>> А можно и адщфе использовать, если использовать в качестве индекса не L>> нужно.
AD>Категорически нельзя. В данном примере идеология плавающей точки гарантирует кучу геморроя при инкременте числа, вплоть до бесконечного цикла (при достаточно большой величине константы ZNACHENIE).
C double можно. И никакого гемороя. Пока __int64 не было все так и делали.