![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
В С++ имеется тип переменных как float так и double. Переменные типа double могут хранить значения на много больше ежели переменные типа float, и с большей точностью.
Возник вопрос. Зачем тогда нужен тип float вообще? |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
||||
|
||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
||||
|
||||
Cheloveck |
|
||||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1578 Регистрация: 26.7.2008 Где: Тула Репутация: 5 Всего: 32 |
Боюсь, что это не совсем так.
В любой версии стандарта. Вот первый попавшийся в гугле http://www.open-std.org/jtc1/sc22/wg21/doc.../2005/n1905.pdf
-------------------- ![]() |
||||
|
|||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
ну само имя double - что-то да значит (смотрите перевод, если что... ![]() Ну и в реале, так оно и есть почти везде.
в стандарте об этом ничего конктретного, как всегда не говорицца... ![]() Так что смотреть стандарт - терять время. Нужно смотреть доку компилятора или чтоб не морочить долго голову, просто написать небольшую программку, и все сразу станет ясно.
http://codepad.org/byh5i3L2 Добавлено через 4 минуты и 19 секунд В студии, кстати, точно также. |
||||
|
|||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Cheloveck, так там написано же что мол каждый последующий из типов float - double - long double хранит значение переменных большей величины.
Множество значений float является подмножеством значений double, и множество значений double является подмножеством значений long double. floatiing-point определяемые-реализацией... Это что за такое? Integral и floating-типы называются более верно арифметическими типами. Согласно специализации классов std::numeric_-limits 18.2 определены максимальные и минимальные значения каждого арифметического типа согласно их применения. Перешёл я в ту спецификацию 18.2 и не нашёл там рамок для соответствующих типов данных. Поясните, пожалуйста, как это правильно искать там? |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
hoz, мою програку смотрели на codepad.org, там показано как использовать numeric_limits
Сам стандарт, как я уже говорил, никаких границ не дает. Все зависит от реализации компилятора. |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
грубо означает что нужно смотреть не в стандарт языка, а в стандарт который выбрала реализация, например сюда : http://ru.wikipedia.org/wiki/IEEE_754-2008 |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Стрго говоря, (раз уж здесь все так офигенно стрго, как я погляжу). Нужно сначала выяснить в той же доке компилятора, что он использует именно IEEE_754-2008 в качестве реализации плавющих типов. Что вовсе не обязательно. А уже потом, при положительном ответе, можно и смотреть туда, куда вы указали. только сколько это все займет время у новичка интересно... ![]() |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
да, правда что ли ? но простите, а я что написал ?? или опять упреки в софистике посыплятся ? |
|||
|
||||
hoz |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Хм. Я пока что Ваш код не совсем понял, хотя с большего, конечно, логика проста. Но С++ изучаю пока что с нуля (после примитивного mql4), так что сложновато на данном этапе. Вот, есть момент.
Переменная size указывает на количество символов в значении, верно? А range, как видно диапазон. Тока вот что значит запись 1.17549e-38 не понимаю.. |
||||
|
|||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
как это соотносится с вопросом на который и был ответ ? или Вы предлагаете кому то другому посмотреть доку компилятора новичка и определить нужный стандарт ? не пойму только кому... Добавлено через 4 минуты и 4 секунды https://ru.wikipedia.org/wiki/%D0%AD%D0%BA%...%B8%D1%81%D1%8C |
|||
|
||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Не предлагаю, я писал тот пост до того как volatile ответил. Но меня реально грузит всё это. Такое ощущение, что там всё спецом так запудрили. Лезть в доку компилятора я и не собирался. Раньше я даже не знал, что придётся... |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
hoz, ![]() Добавлено через 2 минуты и 10 секунд да потому что в принципе в первую очередь операции с плаваюшей запятой зависят от процессора, а не языка.. |
|||
|
||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Так странно. Если:
Получается, что sizeof возвращает размер его операнда, а range согласно коду диапазоны макс. и мин. Но size=4, а у range размеры огромных пределах, я даже не представляю себе эти числа. Но там далеко не 4... (для float). Как это понимать? Это сообщение отредактировал(а) hoz - 14.7.2013, 01:13 |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
![]() --- Ребята хорош грузить новичка. Вы конечно все очень правы, особенно длинная цитата из стандарта Это напомнило мне старый анедот. ![]() Как-то летели Холмс с Ватсоном на воздушном шаре. И заснули. Просыпаются над какой-то незнакомой местностью, видят - внизу какой-то мужик коров пасет. Снизились они и спрашивают мужика: - Скажите, сэр, где мы находимся? - (хорошенько подумав) На воздушном шаре. - Спасибо, сэр! - и поднялись вверх. Холмс задумчиво говорит: - Интересная местность, Ватсон! Программист пасет коров! - Но, Холмс, с чего вы взяли, что он программист? - Элементарно, Ватсон! Во-первых, он ответил, хорошенько подумав. Во-вторых, его ответ - Абсолютно точен. Ну и в третьих - Абсолютно бесполезен! |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
> Получается, что sizeof возвращает размер его операнда, а range согласно коду диапазоны макс. и мин. Но size=4, а у range размеры огромных пределах
ИМХО для начала нужно разобраться хотя бы с целыми числами. Там такая же фигня. При size равном 1 байт range от 0 до 255. И ещё, смысл double не в хранении больших чисел, а в большой точности при хранении чисел. Кстати, на некоторых процессорах double вообще нет. Есть только float. Например, на некоторых GPU. -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
имелось в виду "в большей" ? |
|||
|
||||
borisbn |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 4875 Регистрация: 6.2.2010 Где: Ростов-на-Дону Репутация: 21 Всего: 135 |
> имелось в виду "в большей" ?
Ну... Я там обыгрывал "большие числа" vs "большая точность", но и так можно ![]() -------------------- Женщины отличаются от программистов тем, что у них чары состоят из стрингов |
|||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
1.17549*10^-38=1,9999 9259*2^-127=1, 1111 1111 1111 1111 1000 011*2^-127. Причем старшая 1 в мантиссу не пишется. Так?
Это сообщение отредактировал(а) Wuffur - 15.7.2013, 09:31 |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 4 Всего: 459 |
Я думаю, что флоаты в первую очередь нужны для скорости. Одно дело вычислять ~7 знаков акртангенса для флоата, и совсем другое 14 знаков для дабла. Оно конечно зависит от реализации в процах, но по опыту даблы будут раз в 10 дольше вычисляться если не хуже. Поэтому графику считают флоатами, тем более что флоаты лучше оптимизируются SSE . Я бы сказал, что скорее даблы не нужны чем флоаты, но они безусловно нужны для научных вычислений где требуется сохранение точности.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
Зависит от задачи - когда для скорости, а когда, чтобы вместились в память. Если вы CUDA программист, то там производительность сравнима,
здесь: http://www.nvidia.com/object/tesla-servers.html пиковая производительность на кеплере. А здесь просто про floating point на CUDA^ https://developer.nvidia.com/sites/default/...ating-Point.pdf K20 Peak double precision floating point performance 1.17 Tflops Peak single precision floating point performance 3.52 Tflops PU Computing Applications Reservoir simulation, CAE (structural analysis), Molecular dynamics, Numerical analytics, Computational visualization (ray tracing) Вполне возможно, что если вам нужно отрисовывать сложную сцену, то без double не обойдешься. Это сообщение отредактировал(а) Wuffur - 15.7.2013, 09:55 |
|||
|
||||
akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
Вопрос исторический и поэтому немного риторический.
Надо смотреть, как появлялись float и double. Смотреть аллюзии с fortran'ом, потому что первоначально он в основном использовался для научных расчётов, a C рассматривался как системный язык (точность нецелочисленных вычислений в fortran'е была побольше. PS. Как сейчас, не знаю.) А дальше уже идут вопросы переносимости кода. Стандарт языка, кажется, на то и стандарт языка, чтобы в нём не рассматривалась трендовая текущая ситуация с hardware и software, а важна универсальность. Даже до сих пор есть DJGPP, который компилит код под 386 процессором и, пусть и единичные, но у людей возникают задачи что-то написать и откомпилить, работающее даже на 286 процах. Не говоря про многообразие UNIX'оидных тачек. Добавлено через 8 минут
В большом ряде научных расчётов такая точность может оказаться недостаточной. Так что не грузите новичка, а расскажите ему так, как оно есть на самом деле. "Как к такой жизни пришли" и почему оно до сих пор так, а не по другому. Это сообщение отредактировал(а) akizelokro - 15.7.2013, 10:11 -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
akizelokro,
А вот если я ему скажу, что на два это число делить можно, а на большее целое будет ноль - это будет ответ на вопрос? Может он сам додумает? С вашим ответом, что в DJGPP всё устроено как в 286 и 386 вряд ли понятнее станет. Я вот знаю, что сопроцессор для вычислений с плавающей точкой появился только на 386 DX-2 и там ни о каких double речи не шло. Просто Doom 2 быстрее стал идти. |
|||
|
||||
hoz |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Мда. Пользуюсь уже год как числами с запятой, а ничего про них не знал до этого момента
![]() В принципе, вы было сказано верно, double больше float по сайзу в байтах в 2 раза, но long double относительно double уже не в 2.. хотя значения его в диапазоне на порядок больше предшественника, как в нормализованном виде, так и в денормализованном виде. Есть пару моментов. 1. Ведь переменная у которой мантисса с порядком имеет значение 1,2·10−38 или 1,2·10−38 это уже 38 запятых в ту или иную сторону. Зачем больше? Как программист прикидывает всё-таки необходимость использования того или иного типа? Лично я не представляю, где можно использовать такие числа... с такой точностью. А выше и подавно. Очень интересно понять. 2. Тут сказано, что:
Это как понять? 3. Ещё там есть такое:
Разве может быть мантисса отрицательной? Ведь, если так, то вид:
Будет правильным? Это сообщение отредактировал(а) hoz - 15.7.2013, 15:10 |
||||||
|
|||||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Нет))) Это значит, что порядок числа может быть от -38 до +38, но вот число значащих цифр - всего 7-8 (у double - 15-16). А точнее? Может: -1.0... Нет. -0,1·e3 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
hoz |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Хм. Я так понял, Вы из той таблицы взяли? Для long double согласно той таблицы будет от 19-20 знаков.. Выходит, что нас интересует именно точность! Теперь понял. Я уже исправил в своём посте, вот что я имел ввиду:
Читал, читал.. но не очень понятно, что они имеют ввиду под терминами фиксированной и относительной точности. Хотя да. Верно. |
||||
|
|||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Нет, это довольно известные факты))) Да! Можете взглянуть на строение float ![]() Ну вот всё тоже самое))) Число бит под мантиссу фиксировано, значит, Вы можете, к примеру, различать числа x=1.0eN и y=1.000001eN (где N - какой-то порядок); а 1.0eN и 1.0000001eN уже не различаются (не хватает разрядности мантиссы и 0.0000001 отбрасывается). Поэтому (максимально достижимая) относительная точность
не зависит от порядка числа и зависит только от разрядности мантиссы. В то же абсолютная точность
просто совпадает с x*1e-6 и изменяется вместе с x (и его порядком). Это сообщение отредактировал(а) feodorv - 15.7.2013, 16:46 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Ничего там непонятно вообще, если честно. Думал что всё понятно, а как начал там читать, так затуманило. Наверное лучше оставить "как есть", ведь различия в применении типов переменных я выяснил, а дальше уже дебри.. Который пугают ![]() Во втором варианте, Вы имеете в виду, что там N-не порядок мантиссы, а множитель что-ли? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
А чего непонятного? Число с плавающей точкой состоит из 3-х частей: знак (-1 или +1), мантисса (от 0 до 1) и экспонента (от -128 до +127). Фактическое число получается так: s * m * 2 ^ e. Подробнее в вики |
|||
|
||||
akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
Не знаю. Я помню, что в fortran'e тогда были float, и double precision, и все равно не хватало, стали вводить huge. Но с huge слава богу дело так и не пошло, сейчас глянул, там есть extended precision c 16 байтами под число. Добавлено через 10 минут и 35 секунд так будет лучше всего. просто знай вот эту разницу, а если ты не занимаешься конкретной тематикой, где нужна точность, тебе это знание может и не пригодиться никогда. Выпавший зуб даю! ![]() Просто прими как данное, что для универсальности в С/C++, да и не только есть много вещей, которые, создавайся язык прямо сейчас, были бы не нужны 15-20 лет назад чуть ли не байты считались, чтобы уменьшить размер исполняемой программы. Поэтому, imho, тогда и была введена разница между int и long, например. Но остались и старые программы кое-где и старый код. Остаётся либо жертвовать обратной совместимостью и универсалностью, либо сейчас думать, зачем нужно такое конкретное разделение между целочисленными int и long, когда на современной технике возможная разница между ними уже ничего не значит. Почти не значит. -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Вот скрин страницы учебника:
![]() Как выше обсуждалось, неявное приведение типов отрабатывается в случает надобности, если того требует ситуация (наличие переменные разного типа в выражении). Тут то ли перевод нечёткий, то ли автор не так выразился. Решил я переспросить. Там сказано, что:
Но точность переменных типа float 7-8 знаков, а значит 1000.0 и .05 вполне потянет тип float, а значит не разумно производить неявные преобразования и расчёт с данными переменными в таком виде... Я прав? Ведь 1000.0 - тут порядок мантиссы 1, а у .05 - 2. Как раз float тут самое то, т.к. по скорость расчёта, так и потому, что он поддерживает данную точность. А автор учебника утверждает, что типа нет судя по контексту. |
|||
|
||||
feodorv |
|
||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
"Структура for"? В смысле "управляющая структура кода" (или "структурный оператор")? Почему не просто "оператор цикла for" - получилось бы два раза рядом стоящих слова "оператор"?
Потянет.
Наверное, он всё-таки хотел иметь в виду другое. Математические функции, определённые в заголовке math.h, практически все работают с double, в том числе и pow. Особого смысла (в данном примере) преобразовывать float-аргумент к double, а затем результат из double во float, нет. Поэтому будем работать с double:
А то, что дальше
мне видится как копипаст от предыдущего утверждения. Какие проблемы. Пробуйте с float. Потом сравните результаты с double. Для большого числа лет результат должен заметно отличаться... Для 10 - незначительно... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||
|
|||||||
hoz |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Как это пробывать? Ведь сказано же тут, что:
Получается, преобразование происходит даже когда нет необходимости.. Я вот заметил, что это не разумно. Потому и спросил. Ведь если не требуется высокая точность, а расчёт её учитывает, как это иначе понимать? |
||||
|
|||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 4 Всего: 459 |
На самом деле сопроцессор можно настроить на точность вычислений. Можно сделать так, чтобы он считал даблы с точностью флоатов (библиотеки DirectX так и делают) . Вообще, преобразование операция простая, так что можно не париться.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Напишите свою fnpow ![]()
Необходимость есть, и связана она с типом аргумента функции pow. Вот если была бы библиотечная функция fpow(float,float), тогда другое дело. Но что есть, то есть. Мне всё же не понятно возмущение по поводу double. Ныне (если не брать в рассмотрение особые случаи) это стандартная единица для представления чисел с плавающей точкой. Современные (со)процессоры работают именно с double (хотя Вам кажется, что с float). То есть даже если вы будете пользоваться float, процессор всё равно преобразует float в double (а то и в long double), и уже потом будет складывать, вычитать, умножать, делить etc. Даже printf не умеет печатать float, минимум double (хотя scanf умеет работать с float). -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Получается тут "виновник торжеств" не функция pow, а аргументы... Автор выразился видимо не особо внятно, по крайне мере я так подумал. Теперь понял. Хотя проще же было сделать по дефолту, чтоб типы данных в аргументах функции pow были пользовательскими. Это же логично.. Получается, опять же float как тип уже не востребован, что и требовалось доказать. Если уж его игнорят современные процы. Это сообщение отредактировал(а) hoz - 17.7.2013, 14:26 |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 4 Всего: 459 |
Это давнее заблуждение. То что регистры двойной точности еще не значит, что вычисления выполняются одинаково быстро. Арифметические плюс минус умножить делить, возможно, да и то деление и умножение наверняка с флоатми заметно быстрее. А если перейти к тригонометрическим функциям, то картина меняется кардинально. Время вычисления тригонометрических функций растет значительно быстрее чем точность. В некоторых компиляторах отсутствуют функции sinf, точнее они реализуются через sin , поэтому там нет разницы float/double, но это нифига не правило. На отдельных алгоритмах с использованием функций типа sin/arctan/sqrt у меня получалась разница в 50 раз и больше. Это небо и земля. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
Машинное эпсилон для IEEE 08 float32: 2^-24 = 5.96e-08 , так что почему нельзя 1.000001eN, где 0.000 0001 = 1*10^-7 я не знаю.
Для самообразования: http://en.wikipedia.org/wiki/Machine_epsilon Это сообщение отредактировал(а) Wuffur - 17.7.2013, 14:40 |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Я написал: "к примеру" ![]() Ок))) Ну почему. Если Вам критично использование памяти и не критична точность с расширенным диапазоном, тогда float является спасением (если, конечно, на Вашей платформе float "в два раза меньше места занимает"))). Вот и Alexeis говорит, что кое-где весьма бережно относятся к float. И таки дают функции с float'ами. Ещё выше писали про графику, SSE и т.д. float используется, и используется активно))) -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 4 Всего: 459 |
У кого есть поновее компилятор под рукой проверьте следующий код
Старичок VS2005 выдал флоаты в 2 раза медленнее даблов, но есть подозрение, что у него нет sinf . С графикой я четко замечал влияние _control87(_MCW_PC, _PC_ХХ); Т.е. несмотря на 64х битность сопроцессора он вполне умеет считать и с пониженной точностью для флоатов. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Тема разраслась, начались вещи писаться, который уже за гранью темы и моего понимания в частности.
Я выше уже спрашивал про то, как понять:
Например, берём числа: 123245.84, 457235.1, 235,6882347 У каждого из них будет фиксированная точность и изменяющаяся? Я сколько не читаю про это, что-то не въезжаю. |
|||
|
||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Давайте так. Кроме представления чисел в форме "числа с плавающей точкой" есть представление числа в форме "число с фиксированной точкой". С точки зрения точности представления чисел эти две формы являются противоположными:
Для чисел с фиксированной точкой
Конкретное число x в машинном представлении (в силу ограниченности возможностей представления различных чисел на ЭВМ) может являться совсем другим числом X (округлённым до ближайшего "машинного" числа). Поэтому возникает погрешность машинного представления: вместо x имеем X. Задача: оценить эту погрешность. Погрешность можно оценить в лоб: |x-X| - насколько расхождение абсолютно. Можно более тонко - соизмерять с исходным числом: |x-X|/|x| - это уже относительная погрешность. К примеру: в корпорации "РосМама" счётная палата выявила финансовую отчётность на 99 млрд рублей из 100 млрд финансирования, а в компании "ВасяПупкин" смогли оправдаться за 300 тысяч из 400 тыс бюджета. Вопрос: кто из них больший растратчик? Так вот с точки зрения относительной погрешности "РосМама" растратила всего 1%:
Вот причём здесь конкретное число? И куда делись основополагающие термины "относительная" и "абсолютная"? Для любого X в форме числа с плавающей точкой верно:
Это сообщение отредактировал(а) feodorv - 18.7.2013, 08:51 -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Alexeis, так время измерять нельзя! Оптимизатор там просто вообще выбрасывает холостые циклы, так как результат никуда не используюцца. У меня ваш код выдавал крайне не стабильные результаты При добавления накопления и вывода результата, время вычислений возросло на 2 порядка (~100 раз)!!! (что явно свидетельствует что в вашем коде, оптимизатор просто выбрасывал не нужные вычисления) И время, после коррекции стало примерно одинаковым (+/-2%). Кроме того там есть и еще ошибки. Если не ошибаюсь, вы здесь перепутали местами маску и значение. То есть нужно писать наоборот:
проверьте здесь |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Для каждого числа будет определена абсолютная и относительная точность представления в форме числа с плавающей точкой:
-------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
Давайте ещё про long double похоливарим.
![]() |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 4 Всего: 459 |
Да, был неправ на счет тригонометрических функций. Для AMD64/x86 процов нет специальной реализации sinf/atanf . Сопроцессор считает их исключительно как double . У него просто нет аппаратных вычислительных блоков разрядности 32. Для тригонометрии получается double будет работать быстрее за исключением случаев не хватки кэша процессора.
Но я вот провел другой эксперимент не зависящий от кэша проца. Для складирования использовал массивы небольшой размерности (на 100 элементов), так чтобы double и float были в равных условиях. Кроме того, чтобы компилятор не филонил, зарядил даже вывод результатов на экран. Вот такой получился код
Результат для float -в получился в 2 раза быстрее. Причем SSE2 мало влияет на результат, поскольку такой код не очень хорошо оптимизируется. Зато разница по скорости тем заметнее чем сложнее выражение. По-моему это явно указывает на то, что сопроцессору не все равно с одинарной или двойной точностью считать. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Alexeis,
![]() Только у Вас там стоит _PC_64, что на мой взгляд означает long double, а не просто double. -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 4 Всего: 459 |
Мантиса у дабла 53 бита? Нужно попробовать с _PC_53 тогда.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Вероятно да, это так. Но сам по себе выбор типа: float или double - никакой роли на точность сопроцессора, а следовательно на скорость, не оказывают. Например, если перед дабл-вычислением поставить _control87(_PC_24, _MCW_PC); то будет считать с такой - же скоростью как и float. (и вероятно, с такой-же реальной точностью.) В общем здесь весь фокус в инструкции _control87 (); Но это же чисто мелко-мягкая фича, как я понимаю? |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 4 Всего: 459 |
Да, имеется такая пакость, когда имеешь на руках "половинные" даблы. Реально считается только половина цифр. И занимают кучу памяти и нифига не точные. А как можно повлиять на софтовом уровне на скорость операций? Мне кажется только аппаратно можно повлиять. -------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Ну вот в связи с этим, на вопрос новичка "зачем нужен float?" отвечать - для увеличения скорости, всеже не совсем верно. скорость увеличиваецца не от float, а от какиx-то аппартных (плохо/не переносимых) штучек. О которых новичку вовсе пока не нужно знать. Да и НЕ новичку кстати тоже (помним о "premature optimization"), только если уж совсем подопрет... Правильным-же ответом на вопрос "зачем нужен float?" все-же будет - экономия памяти. нет? |
|||
|
||||
Alexeis |
|
|||
![]() Амеба ![]() Профиль Группа: Админ Сообщений: 11743 Регистрация: 12.10.2005 Где: Зеленоград Репутация: 4 Всего: 459 |
volatile, ну если С++ это только AMD64 и x86 то да. Есть много железяк где нет 64х битного сопроцессора, на некоторых совсем нет никакого даже 32х битного и float-ы вычисляются программно через библиотеки идущие в комплекте с компилятором. В общем случае, float должен быть не медленнее double, a double не медленнее long double. Если пишется универсальный программный модуль, то это следует учитывать.
-------------------- Vit вечная память. Обсуждение действий администрации форума производятся только в этом форуме гениальность идеи состоит в том, что ее невозможно придумать |
|||
|
||||
hoz |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Мда. Вроде как уже не первый день программирую. По крайне мере, кой-чиво уже писал. А вот эти основы для меня самые трудные для понимания. Уже казалось бы, и так и сяк кручу и верчу. Но как-то не всё улаживается в голове.
Взять хотя бы понятия абсолютная погрешность и относительная погрешность. О погрешностях я прочитал тут тут Вот как у чисел с фиксированной точностью может быть так:
А у чисел с плавающей точкой (запятой) иначе:
Понять не выходить. Относительно чего всё это анализировать? Думаю, если оно не пригодится дальше, может вообще пропустить ![]() ![]() Хотя хочется уже добить этот момент и дальше свободно всё штудировать. |
||||
|
|||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Я бы забил)))
Ну, если охота пуще неволи... Что именно в этом абзаце не понятно: Для каждого числа будет определена абсолютная и относительная точность представления в форме числа с плавающей точкой:
Как видно, абсолютная погрешность представления меняется (в зависимости от представляемого числа), поэтому она "изменяющаяся". И "изменяющаяся" она не для конкретного выбранного числа (в зависимости от фаз Луны, что ли, сегодня одна, завтра - другая))), а меняется вместе с представляемым числом. В то же время относительная погрешность никак не меняется при выборе представляемого числа, поэтому она "фиксированная"... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
||||
|
||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
О господи, e-2 - это порядок в десятичном представлении. 1.0 - мантисса в десятичном представлении. Разница между, к примеру float2, который 2^-8(если первая не значащая) последним битом и следующим в памяти за ним числом(предпоследний бит представлен для +inf,-inf и различных NaN, подробнее в википедии) и есть машинное эпсилон. Только сначала нужно перегнать всё в двоичное представление, а это сделано для простоты восприятия программистом. ![]() Feodorv, и ни надо новичкам в десятичном представлении числа с плавающей точкой показывать, пусть учатся, а то будет у них глупое представление, которое потом из них не выбьешь. ![]() К тому же сам немного ошибаешься. Это сообщение отредактировал(а) Wuffur - 21.7.2013, 16:45 |
|||
|
||||
feodorv |
|
||||||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Ээээ, нет. Постойте. Буковка e в записи числа указывает, что дальше пойдёт целое число, означающее прядок числа:
Эти примеры понятны? (.0 в записи числа с плавающей точкой - необязательны, но приведены для порядка). Что же такое эпсилон? Находим ссылку, которую дал Wuffur: Для самообразования: http://en.wikipedia.org/wiki/Machine_epsilon Заходим по ней, видим название статьи: Machine epsilon. Так вот он, какой эпсилон - машинный! Для float это значение равно 2 ^ -24 = 5.96e-08. Что это значит?
То есть для разницы машинного представления и первоначального числа: |X - x| < (X * 5.96e-08) или двойное неравенство X - (X * 5.96e-08) < x < X + (X * 5.96e-08) А с чего вдруг моё хорошее число x может превратиться в какое-то машинное X? И вот тут хочешь-не хочешь, а придётся разбираться с форматом представления чисел с плавающей точкой (ссылка от bsa: Число одинарной точности) Внезапно выяснится, что и мантисса, и порядок находятся в двоичной системе счисления (а не в десятеричной!), что лидирующая единица не участвует в представлении числа, но держится в уме и т.д. и т.п. И вот с этого последнего и стОит начинать разговор. Всё остальное - лирика... Добавлено через 5 минут и 4 секунды Ух ты, пока писАл, Wuffur, уже ответил)))
Я жеж только за! Я и за полную и неприкрытую правду))) Где, в чём? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||||||
|
|||||||||
Wuffur |
|
|||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
В том что если умножить 10^n это то же самое что 2^m, которое и указывает порядок. С помощью 1.0e-2 указывает, что на экран вывелось именно 10^-2, а не 2^-8. Мантисса (1),0100011, для float32. И машинное эпсилон надо умножать на 2^-8. Это сообщение отредактировал(а) Wuffur - 21.7.2013, 17:57 |
|||
|
||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Ну да, надо было начинать с начала (с формата чисел), а не с конца... Хотел как лучше))) В каком смысле? Чешу репу))) Вот тут всё нормально: http://codepad.org/6J68wSlx Откомпилированное на MS VC 6.0 (какой уж под рукой))) даёт:
Это результат зверской оптимизации у Microsoft? -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
Wuffur |
|
||||||
Новичок Профиль Группа: Участник Сообщений: 45 Регистрация: 22.7.2007 Репутация: нет Всего: нет |
Ничего не знаю. ![]() Мой gcc:
Даёт:
Наверное msvc 6.0 слишком умный %f - float, %d - double. Это сообщение отредактировал(а) Wuffur - 21.7.2013, 21:31 |
||||||
|
|||||||
hoz |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
В общем-то, Благодарю всех за обсуждение! Буду дальше изучать язык. К этому вопросу вернусь позже, дабы полностью прояснить ситуацию. Пока что уже я и так понял разницу, и много того чего не знал, капаясь в вики. Но чтоб понять целостную картину, видимо нужно больше времени.
|
|||
|
||||
akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
Целостную картину можно было понять уже на первой странице.
Просто гуроны (от слова "гуру") решили поблистать. И это достаточно понятное и нормальное побуждение. Мало какой эксперт не воспользуется ситуацией. А есть жёсткая прагматика. Если вопрос достаточно сложен (много информации), то, когда перестаёшь работать с ним постоянно, мелкие детали вымываются из памяти. И при возврате к ним всё равно снова приходится садиться за справочное пособие. Это сообщение отредактировал(а) akizelokro - 23.7.2013, 16:27 -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
feodorv |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
akizelokro, слишком много букв, да?
![]()
Повторение - мать учения))) Ой, да ладно. Блеска здесь не наблюдается. Но вот попробуйте доходчиво ответить на вопрос:
А я на Вас со стороны посмотрю ![]() -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
||||
|
|||||
akizelokro |
|
|||
![]() Крокодил ![]() ![]() Профиль Группа: Участник Сообщений: 761 Регистрация: 30.7.2007 Репутация: 1 Всего: 5 |
Вы бы лучше на меня в 90ых посмотрели, когда я смотрел на флаги форматирования функции printf., работая с float и double раз в сто лет в обед. И рассуждал так.. у int флаг i, у лонгов - l, у char - с, у unsigned - u, значит, у float - f, у double - d (это на память). Самое интересное, что f для float срабатывало, и потом я уже с полной уверенностью писал для double - d! (и черта с два интернета было под рукой, чтобы посмотреть, как оно надо). После выдачи с d неожиданного результата глаза собирались в кучу и озирали строку вывода) Кстати, для флага f тип по умолчанию double.
Ну, я смотрю на это философски. В моё время была хорошая математическая подготовка, сейчас больше, имхо, люди приходят с веб-программирования, там больше уклон уже не на математическую базу. Закономерный этап. Это сообщение отредактировал(а) akizelokro - 23.7.2013, 17:34 -------------------- a = a + b; b = a - b; a = a - b; |
|||
|
||||
feodorv |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 2214 Регистрация: 30.7.2011 Репутация: 12 Всего: 45 |
Это особенность всех функций с переменным числом аргументов: float расширяется до double, и всё тут, живи как хочешь))) Ну да, в принципе могли бы и так сделать, оставив %d (от digital) для double, а %i для целых (от integer). Но история пошла другим путём... -------------------- Напильник, велосипед, грабли и костыли - основные инструменты программиста... |
|||
|
||||
volatile |
|
||||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
В данном случае нужно отсылать к учебнику за 4-5 класс средней школы. Человек не понимает разницы между "абсолютно" и "относительно". (не важно о чем речь, о погрешности, или о прибавке к зарплате...) А он именно этого не понимает. |
||||
|
|||||
hoz |
|
||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 27.6.2013 Репутация: нет Всего: нет |
Вообще нет, не этого. Я не понял в том момент когда писал, что для чисел определённого типа применимы разные точности:
И, именно по этому, были заданы вопросы. Вышло так сказать, противоречие. |
||||
|
|||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |