T>>А в качестве индекса все равно поиспользовать не получится... хоть double используй, хоть __int64.
LVV>Предел float 10^38 = 2^38*5^38 LVV>2^42 = 2^4*2^38 = 16*2^38 LVV>Очень даже организуешь! LVV>Или я где-то грабли не вижу?
Конечно не видите, что, вообще говоря, странно...
Распределение вещественных чисел, представляемых флоат (да и любым числом с плавающей точкой) на множестве вещественных чисел, неравномерно. Наиболее плотно числа представлены (отбросив знак) в районе единицы, далее, ближе к границам диапазона — значительно более разрежено. Т.е. далеко не все целые числа из диапазона флоата можно с точностью до +-0.5 им представить. Более того. Общее количество (вещественных) чисел, представляемых float, составляет примерно (точно я не помню) 2^25 + 1. Общее количество (вещественных) чисел, представляемых double, состоявляет 2^53 + 1, т.е. им представить 42 битное число с некоторой осторожностью можно (при этом, очевидно, от операции инкремента в виде прибавления единички к значению придется отказаться, придумав нечто другое, что не изменяло бы значения порядка, а только мантиссы). В общем — правильнее и быстрее использовать вложеный цикл на long, если компилер не поддерживает 64-х битные целые.
Здравствуйте, Tan4ik, Вы писали:
maq>>>Если нет то можно реализовать с использованием двух 32-х битных LVV>>А можно и адщфе использовать, если использовать в качестве индекса не нужно.
T>адщфе = float? T>Тогда ты не прав. Флоат всего 4 байта и цикл, перебирающий 2^42 значений, на нем никак не организуешь. T>Вот на double можно организовать. У него одна мантисса 52 бита.
C doublom-то понятно! T>[msdn] T>Type Exponent length Mantissa length T>float 8 bits 23 bits T>double 11 bits 52 bits T>[/msdn]
T>А в качестве индекса все равно поиспользовать не получится... хоть double используй, хоть __int64.
Предел float 10^38 = 2^38*5^38
2^42 = 2^4*2^38 = 16*2^38
Очень даже организуешь!
Или я где-то грабли не вижу?
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, emergenter, Вы писали:
E>подскажите пожалуйста как выполнить цикл
E>
E>for(i=0 i<ZNACHENIE; i++)
E>{
E> ....
E>}
E>
E>где значение это 42 битное число??
Может быть быть имеет смысл переделать сам алгоритм? Даже просто перебор 42-битного счетчика весьма ресурсоемок. А если в цикле будут хоть какие-то вычисления, то это будет долгий цикл.
Здравствуйте, emergenter, Вы писали:
E>подскажите пожалуйста как выполнить цикл
E>
E>for(i=0 i<ZNACHENIE; i++)
E>{
E> ....
E>}
E>
E>где значение это 42 битное число??
В этом случае и i должно быть не менее чем 42 бит, если компилятор поддерживает
64х битные переменные (__int64 или long long) то просто используйте их.
Если нет то можно реализовать с использованием двух 32-х битных
E>>где значение это 42 битное число??
maq>В этом случае и i должно быть не менее чем 42 бит, если компилятор поддерживает maq>64х битные переменные (__int64 или long long) то просто используйте их.
maq>Если нет то можно реализовать с использованием двух 32-х битных
А можно и адщфе использовать, если использовать в качестве индекса не нужно.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
E>>>где значение это 42 битное число??
maq>>В этом случае и i должно быть не менее чем 42 бит, если компилятор поддерживает maq>>64х битные переменные (__int64 или long long) то просто используйте их.
maq>>Если нет то можно реализовать с использованием двух 32-х битных LVV>А можно и адщфе использовать, если использовать в качестве индекса не нужно.
адщфе = float?
Тогда ты не прав. Флоат всего 4 байта и цикл, перебирающий 2^42 значений, на нем никак не организуешь.
Вот на double можно организовать. У него одна мантисса 52 бита.
Здравствуйте, LaptevVV, Вы писали:
maq>>>>Если нет то можно реализовать с использованием двух 32-х битных LVV>>>А можно и адщфе использовать, если использовать в качестве индекса не нужно.
T>>адщфе = float? T>>Тогда ты не прав. Флоат всего 4 байта и цикл, перебирающий 2^42 значений, на нем никак не организуешь.
LVV>Предел float 10^38 = 2^38*5^38 LVV>2^42 = 2^4*2^38 = 16*2^38 LVV>Очень даже организуешь! LVV>Или я где-то грабли не вижу?
int main()
{
float a=1;
for (int i=0; i<10; ++i)
a *= 10.f;
float b=a+10;
cout << "Is 10^10 + 10 == 10000000000?" << endl;
if (a==b)
cout << "Yes, of course!" << endl;
else
cout << "No!" << endl;
return 0;
}
Здравствуйте, 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 им представить.
Наиболее плотно — в районе нуля
AS>Более того. Общее количество (вещественных) чисел, представляемых float, составляет примерно (точно я не помню) 2^25 + 1.
Больше. Намного больше. Чуть меньше 2^32 (меньше из-за того, что некоторые числа имеют неоднозначное представление, но таких чисел очень мало).
AS>Общее количество (вещественных) чисел, представляемых double, состоявляет 2^53 + 1,
Тоже ошибаешься. Порядка 2^64. Как и следовало ожидать.
AS>т.е. им представить 42 битное число с некоторой осторожностью можно (при этом, очевидно, от операции инкремента в виде прибавления единички к значению придется отказаться, придумав нечто другое, что не изменяло бы значения порядка, а только мантиссы).
Осторожность никогда не повредит, но в данном случае можно смело пользоваться double. При условии, что используются только +-*= и значение не вылазиет за 2^52.
AS>В общем — правильнее и быстрее использовать вложеный цикл на long, если компилер не поддерживает 64-х битные целые.
Правильнее? Наверное да. Быстрее? Сомниваюсь. Все зависит от задачи и "внутренностей" цикла.
---
С уважением,
Лазарев Андрей
Re[2]: 42 битное число!!
От:
Аноним
Дата:
01.07.04 10:55
Оценка:
Здравствуйте, Astaroth, Вы писали:
A>От нуля до четырёх квадриллионов... A>Ууу
2^42 = 4 * 2^40 = 4 * (2^10)^4 = 4 * (10^3)^4 = 4 * 10^12
Это всего лишь 4 миллиарда.
А>Может быть быть имеет смысл переделать сам алгоритм? Даже просто перебор 42-битного счетчика весьма ресурсоемок. А если в цикле будут хоть какие-то вычисления, то это будет долгий цикл.
М-да. Если хотя бы по микросекунде, то это 4 миллиона секунд — почти два месяца.
AS>>Распределение вещественных чисел, представляемых флоат (да и любым числом с плавающей точкой) на множестве вещественных чисел, неравномерно. Наиболее плотно числа представлены (отбросив знак) в районе единицы, далее, ближе к границам диапазона — значительно более разрежено. Т.е. далеко не все целые числа из диапазона флоата можно с точностью до +-0.5 им представить. T>Наиболее плотно — в районе нуля
С чего это? Флоат хранится в нормализованом виде с неявной единицой.
AS>>Более того. Общее количество (вещественных) чисел, представляемых float, составляет примерно (точно я не помню) 2^25 + 1. T>Больше. Намного больше. Чуть меньше 2^32 (меньше из-за того, что некоторые числа имеют неоднозначное представление, но таких чисел очень мало).
Да, верно. Имелся ввиду диапазон точного представления целых чисел.
AS>>Общее количество (вещественных) чисел, представляемых double, состоявляет 2^53 + 1, T>Тоже ошибаешься. Порядка 2^64. Как и следовало ожидать.
Аналогично предыдущему.
AS>>т.е. им представить 42 битное число с некоторой осторожностью можно (при этом, очевидно, от операции инкремента в виде прибавления единички к значению придется отказаться, придумав нечто другое, что не изменяло бы значения порядка, а только мантиссы). T>Осторожность никогда не повредит, но в данном случае можно смело пользоваться double. При условии, что используются только +-*= и значение не вылазиет за 2^52.
AS>>В общем — правильнее и быстрее использовать вложеный цикл на long, если компилер не поддерживает 64-х битные целые. T>Правильнее? Наверное да. Быстрее? Сомниваюсь. Все зависит от задачи и "внутренностей" цикла.
Быстрее — однозначно. По производительности будет не сильно ниже, чем с int64.
Здравствуйте, Andrew S, Вы писали:
AS>>>Распределение вещественных чисел, представляемых флоат (да и любым числом с плавающей точкой) на множестве вещественных чисел, неравномерно. Наиболее плотно числа представлены (отбросив знак) в районе единицы, далее, ближе к границам диапазона — значительно более разрежено. Т.е. далеко не все целые числа из диапазона флоата можно с точностью до +-0.5 им представить. T>>Наиболее плотно — в районе нуля
AS>С чего это? Флоат хранится в нормализованом виде с неявной единицой.
Спорить не буду. Но мне всегда казалось, что от -0.1 до 0.1 флоатов больше, чем от 0.9 до 1.1. Но если окажется, что это не так, то я не очень расстроюсь.
AS>>>В общем — правильнее и быстрее использовать вложеный цикл на long, если компилер не поддерживает 64-х битные целые. T>>Правильнее? Наверное да. Быстрее? Сомниваюсь. Все зависит от задачи и "внутренностей" цикла.
AS>Быстрее — однозначно.
Если с индексом ничего не делается, то да. Если делается — не факт.
AS>По производительности будет не сильно ниже, чем с int64.
Может и быстрее быть. Я же сказал "Все зависит от задачи и "внутренностей" цикла".
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 не было все так и делали.