LINUX.ORG.RU

Метапрограммирование - проблемы и пути их решения.

 , ,


12

6

Пичал я тут на днях токенайзел для C++-кода, но всё это меня добило я решил поделится.

Проблема - мне надо было вычислять сложные значения для таблицы в компилтайме, да можно на сишке сделать через жопу(енумы) и макросы, но мне стало лень. Да можно сгинерить, но мне тоже лень.

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

Чтобы не быть голословным пишем что-то типа

constexpr uint64_t f(uint64_t a, uint64_t b) {
  return a + b; 
}
Всё ок, но пишем что-то сложнее, аля:

uint64_t m[] = {0, 1, 2, 3, 4};
constexpr uint64_t f(uint64_t a, uint64_t b) {
  return m[a] + m[b]; 
}

Бида( или это моё неосиляторство плюсов?), дак зачем они запилили эту фичу, если она может лишь галимую примитивщину? Шаблоны ещё ущербней. В чем приемущество? Зачем?

А теперь у меня вопрос к вам, уважаемы батьки и отцы - что мне делать? Я хочу запонять массивы написав генератор, причем и в компилтайме тоже. Я хочу юзать libc, я хочу всё, а у меня нет ничего, почему?

Т.е. я не хочу каких-то макропроцессоров и скриптовых языков - я хочу, чтобы, если я написал constexpr - оно должно до последнего пытаться собрать то, что я написал и уже только тогда, когда оно реально это не сможет - отвалиться.

У меня есть 3 пути: терпеть, пилить свой язык и конпелятор самому( что долго и нудно) и ваш совет.

Ответ на: комментарий от feofan

Продолжайте кормить в девелопменте :) Можно пройтись по торадиционной конспирологической версии создания этого треда.

slackwarrior ★★★★★
()
Ответ на: комментарий от superhackkiller1997

Ты получишь точность исходя из того какую часть радиуса ты примешь за 1.

можно я по старинке, за единицу приму 100% радиуса? Сколько получится число PI?

drBatty ★★
()
Ответ на: комментарий от drBatty

дурачок, на дырках диаметра ~100 посадки с допуском несколько соток. А дырки разные бывают, в дырках 10 точность уже тысячные. И это именно что в танках(образца 1950го года). В вертолётах намного точнее.

Сверлибельные дырки, а в сверлибельных дырках ты просто указываешь диаметр.

только идиоты могут хотеть идеальную копию. Математики этого не хотят. Математическое целое и так идеально. Ты не понял, по мнению математиков — это мир говно, а их формулы — правильные.

Нет, их формулы работают, ибо мир правилен. А в физическом понимании мира целое не идеально.

У меня для тебя плохие новости: этот мир НЕ ложится на int.

99% мира ложится в uint64_t. Остально не ложится в дабл, а тебе ничего не мешает запилить 128битные типы.

ты так и не понял: слил int. Ибо он совсем не похож на то, что мы видим IRL. В реальном мире у нас всё тоже косо, криво, плывёт, точно НЕ равно, и всё хреново. Потому, для моделирования IRL идеален как раз float. Который тоже плывёт, почти как наше, реальное говно.

В мире ничего не плывёт. Флоат плывёт после определёного момента, а до этого момента он не плывёт. Т.е. флоат как инт, но плывёт.

забей ты на математиков. Они простых, действительных чисел уже с дюжину сортов придумали. И все идеальные, и бесконечные.

Это их шиза и я клал на их сорта каках.

Про бассеин - давай мне ответ и расскажи почему его нельзя представить в интах.

superhackkiller1997
() автор топика
Ответ на: комментарий от superhackkiller1997

Побольше, чем на даблах - если ты не способен это понять, то ты глупая лалка.

если ты хочешь больше, чем на double, то для каждого круга тебе нужно считать радиус где-то так в 4 611 686 018 427 387 904 единиц. Тогда в unit64_t точность будет лучше, чем у стандартного double. Осталось придумать эти новые единицы.

drBatty ★★
()
Ответ на: комментарий от drBatty

Это НЕ НУЖНО и для математика, и для программиста. И да, в float сама единица ПЛАВАЮЩАЯ, а вот точка как раз вполне фиксированная. Точность тоже фиксированная, что и нужно на практике. Проблема твоих интов в том, что у них плавающая точность, которая слишком большая для больших чисел, и слишком малая для малых. А в техпроцессах точность тоже плавает, уже говорил, для одного класса точности H7 для 100 точность сотки, а для 10и идёт микронная точность.

Микронной точности ты никогда не добьёшься в реальном мире. Это либо микроны на уровне микрон, либо такого не бывает.

Ничего там не плавает.

ты бредишь.

Так оно и есть.

Никак. Давай вернёмся к пиву. Сколько пива в вагоне?

Что атм ут ебя с пивом?

superhackkiller1997
() автор топика
Ответ на: комментарий от drBatty

Нет, лалка. Он появился из-за того, что твой кр пытались сделать сишку идеальной, а надо было на это забить.

Нужен, нужен.

superhackkiller1997
() автор топика
Ответ на: комментарий от tailgunner

НЁХ в сишке появилась из реального мира, а не от скудоумия K&R

Ну да, например, неопределенный порядок вычисления параметров.

Именно! Хороший пример, ибо _оптимальный_ порядок действительно не определён, и если его определить, то на _большинстве_ CPU код будет тормозить. По этой причине, компилятор самостоятельно определяет нужный порядок, а программист пишет такой код, который одинаково работает при _любом_ порядке.

drBatty ★★
()
Ответ на: комментарий от drBatty

НЁХ в сишке появилась из реального мира, а не от скудоумия K&R

Ну да, например, неопределенный порядок вычисления параметров.

Именно! Хороший пример, ибо _оптимальный_ порядок действительно не определён

Бугага. Бугага. Бугага епт.

Историческая справка: порядок вычисления в ранних компиляторах Си определялся порядком занесения аргументов в стек, ни о какой оптимальности речи не шло. Типичная недоспецификация, бессмысленная и беспощадная.

tailgunner ★★★★★
()
Ответ на: комментарий от superhackkiller1997

Сверлибельные дырки, а в сверлибельных дырках ты просто указываешь диаметр.

facepalm

Хотя чему я удивляюсь? Это тебе в ПТУ объяснят, лет через 10.

Нет, их формулы работают, ибо мир правилен.

А вот этого тебе даже в ПТУ не расскажут, нужно в ВУЗ идти, но это тебе явно не грозит в этой жизни.

99% мира ложится в uint64_t. Остально не ложится в дабл, а тебе ничего не мешает запилить 128битные типы.

Ну попытаюсь объяснить: когда требуются вычисления, ВСЕГДА задаётся погрешность. Причём ВСЕГДА в долях величины. (исключая конечно финансовые расчёты, в которых погрешность тоже задаётся, но более сложным способом, дабы нажиться на таких как ты). Проблема int в том, что его погрешность плавает как говно, а вот погрешность float чётко и однозначно определена. По этой причине, пользуясь float, мы считаем ровно столько бит, сколько требуется по ТЗ. Причём нам абсолютно всё равно, что считать, один и тот же код подойдёт и для нанороботов, и для ОБЧР. Точность будет одинаковая. Почему инженерам нужна именно такая точность — объяснять мне лениво, всё равно не поймёшь.

В мире ничего не плывёт.

Да ладно! Грибы, которые ты куришь, сегодня куда как забористее, чем обычно!

Флоат плывёт после определёного момента, а до этого момента он не плывёт. Т.е. флоат как инт, но плывёт.

Упоролся? У стандартного float точность составляет 23 бита. ВСЕГДА. Кроме случая, когда число равно нулю (точность бесконечна), и случая INF и NaN (точность === НЁХ).

Это их шиза и я клал на их сорта каках.

и правильно для четвёртого класса.

Про бассеин - давай мне ответ и расскажи почему его нельзя представить в интах.

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

drBatty ★★
()
Ответ на: комментарий от superhackkiller1997

Ты и получишь число целых 100% радиуса. Хочешь точнее - бери 10%, 1% и т.п.

у меня как не считай получается 2*PI. ЧЯДНТ?

drBatty ★★
()
Ответ на: комментарий от superhackkiller1997

Микронной точности ты никогда не добьёшься в реальном мире. Это либо микроны на уровне микрон, либо такого не бывает.

ну дык погугли. Допуски и посадки, ЕМНИП.

Ничего там не плавает.

это просто твоя рулетка слишком грубая.

Хотя даже рулеткой если мерить, то танк вечером длиннее, чем поутру. (если твоя рулетка конечно из нормального сплава).

Никак. Давай вернёмся к пиву. Сколько пива в вагоне?

Что атм ут ебя с пивом?

у меня — ничего.

drBatty ★★
()
Ответ на: комментарий от tailgunner

Историческая справка: порядок вычисления в ранних компиляторах Си определялся порядком занесения аргументов в стек, ни о какой оптимальности речи не шло. Типичная недоспецификация, бессмысленная и беспощадная.

и что ты этим хочешь доказать? Что другой порядок будет быстрее? Какой именно?

В i8080 это имело значение только для функций с переменным числом параметров, ибо извлекать аргументы по порядку можно было только в противоположном порядке. А вот в PDP-11 это не имело значения, там SP можно было и декрементировать на выборке. Т.е. там аргументы можно было-бы и в LILO списке пересылать, почему — нет? Ты разве не знал, что чтение в обратном порядке намного медленнее, чем чтение в прямом? (во всяком случае, не быстрее).

drBatty ★★
()
Ответ на: комментарий от drBatty

Хотя чему я удивляюсь? Это тебе в ПТУ объяснят, лет через 10.

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

А вот этого тебе даже в ПТУ не расскажут, нужно в ВУЗ идти, но это тебе явно не грозит в этой жизни.

Очередное бла-бла-бла. Это аналоговый мир - он правилен.

Ну попытаюсь объяснить: когда требуются вычисления, ВСЕГДА задаётся погрешность. Причём ВСЕГДА в долях величины. (исключая конечно финансовые расчёты, в которых погрешность тоже задаётся, но более сложным способом, дабы нажиться на таких как ты). Проблема int в том, что его погрешность плавает как говно, а вот погрешность float чётко и однозначно определена. По этой причине, пользуясь float, мы считаем ровно столько бит, сколько требуется по ТЗ. Причём нам абсолютно всё равно, что считать, один и тот же код подойдёт и для нанороботов, и для ОБЧР. Точность будет одинаковая. Почему инженерам нужна именно такая точность — объяснять мне лениво, всё равно не поймёшь.

У инта есть погрешность? Удивил, ой как удивил.

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

Считай в нанометрах мои инты, представляешь кактаващеда?, тоже будут подходить для всего.

Да ладно! Грибы, которые ты куришь, сегодня куда как забористее, чем обычно!

Ну идиви? Что по твоему в мире плывёт?

Упоролся? У стандартного float точность составляет 23 бита. ВСЕГДА. Кроме случая, когда число равно нулю (точность бесконечна), и случая INF и NaN (точность === НЁХ).

Подели 1 на 3 и погляди точность, до этой точности он не будет плыть( прям как инт, представляешь?), а после неё будет плыть рандомно.

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

А ну да, ну да. Ты глупая лалка, которая делит на ноль каждый выхлоп.

Ты же только что идеализировал и говорил, что твои флоаты будет работать для всего?

superhackkiller1997
() автор топика
Ответ на: комментарий от drBatty

Всё ради тебя и для других лалок - батл тысячителетия дабл вс uint64_t - запить числа пи.

3.141592653589793115997963468544185161590576171875
3.14159265358979323846

Ах ёперный театр - шаблон упал.

superhackkiller1997
() автор топика
Ответ на: комментарий от drBatty

Зачем их придумывать? Они уже есть.

И да, я тебе привел точность твоего дабла и при кажом умножении - ты будешь терять точность. Будешь считать с радиумом в 100метров - будешь терять 3знака из того пи( уже отстование 9знаков от инта) - дальше больше.

Т.е. точность дабла порядка 45бит, что какбэ неслабо сливает.

superhackkiller1997
() автор топика
Ответ на: комментарий от feofan

Ты слишком анскилен? Берёшь дабл - записываешь туда пи из википедии, берёшь uint64_t и зпивываешь туда число из википедии, выпилив из него точку.

    double t =   .14159265358979323846;
    uint64_t t1 = 14159265358979323846ul;
    fprintf(stdout, "%.70f\n0.%lu\n", t, t1);
superhackkiller1997
() автор топика
Ответ на: комментарий от superhackkiller1997

uint64_t t1 = 14159265358979323846ul;

А потом начинается дрочиво с числами, чтобы вычислить площадь круга, и результат при этом не выходил за пределы uint64, вместо банального умножения r*pi.

unC0Rr ★★★★★
()
Ответ на: комментарий от superhackkiller1997

Я в хламину со всеми цитатками доказал, что я говорил про медяшку над кристаллом и про фотолитографию даже не заикался

Ну врете же как обычно.

Метапрограммирование - проблемы и пути их решения. (комментарий)

я лишь сказал, что ваша маска в 90% случаев - это натычка из шаблончиков. Какие тут омегарасчёты нужны?

Метапрограммирование - проблемы и пути их решения. (комментарий)

А что такое маска? Это набор елементов, твои расчёты тут не причем.

Маска не имеет никакого отношение к медяшке над кристаллом. Маска это только фотолитография. Щас Вы конечно начнете вижжать что Вы этого тогда не знали и все это вообще не нужно - и самое интересное, что Вы так и не поняли о чем идет речь, хотя Вам всем ЛОР-ом это объясняли.

Я тебе сказал - сейсморазвдка работает в основном на удаче и нужна лишь для того, что её кдп намного превышает кдп геолога с киркой, но в основном ОНИ ПОЛАГАЮТСЯ НА УДАЧУ. Они не знаю где искать, что искать - он ищу тупо рандомом, но ищат не квадратный метр в час, как киркой, а 100метров в час.

Вы опять бредите о чем не знаете. Обработка данных сейсморазведки, это одна из самых сложных вычислительных задач, которые сейчас решает человечество. Неисчерпаемы три вещи - Вселенная, человеческая глупость и потребности сейсморазведки в вычислительных мощностях. Математический аппарат и теория (которые по Вашему вообще ненужны) там чудовищно сложные, а без них никак данные не обработаешь. А без обработки нельзя указать геологам где бурить. Ооопаньки?

Ладно, вот Вам задачка, балаболище. Все числа в окрестностях единицы. Давайте, я с трепетом жду Ваше решение на int64_t, которое окажется хотя бы не медленней чем решение на флотах. Точность - хотя бы 10 знаков. Надо написать функцию которая считает f вот так:

void superhackkiller1997_super_fail(int N, float x[4], float f[4]){
    float norm[4] = {1, 1, 1, 1}, xn[4] = {1, 1, 1, 1}; 
    f[4] = {0, 0, 0, 0};
    for(int n=1; n<=N; n++)
        for(int k=0; k<4; k++){
            xn[k] *= x[k];
            norm[k] *= n;
            f[k] += xn[k]/norm[k];
        }    
}
Мы возьмем Ваше решение, вызовем его много раз с различными x, и сравним с моим решением (не этим, это можно рассматривать как описание алгоритма) по скорости и точности.

Вперед, удивите нас! Неушто и это для Вас окажется слишком сложно?

ЗЫ Кто понял о чем речь - гусары, молчать;-)

AIv ★★★★★
()
Ответ на: комментарий от superhackkiller1997

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

ну на, ознакомься: http://micromake.ru/old/metodiki/raschet_posadok.htm (там тысячные - это миллионные метра, ибо принято в миллиметрах размер писать, в ТяжМаше).

Очередное бла-бла-бла. Это аналоговый мир - он правилен.

ВНЕЗАПНО: мы в «цифровом» мире живём. В дискретном. Да, я понимаю, школьнику это учитывать совсем не нужно. Но знать уже пора-бы.

У инта есть погрешность? Удивил, ой как удивил.

Да, есть. Например в целых бутылках пива, действительно не бывает целой бутылки, полной чуть более, чем наполовину. Средняя погрешность целого числа == ½, а максимальная == 1.

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

шаг не рандомный, а вполне определённый. Погрешность — вполне определённая величина, измеряемая инженерами в долях или процентах, а программисты предпочитают двоичные логарифмы величины, которые называются «биты». НЁХ вполне можно взвесить и посчитать. Погрешность float равна 23 бита, а погрешность int зависит от величины этого int, и равна 1 единице младшего разряда. Вот та же рулетка даёт отличную точность, если мерить ей десятки метров, и точность ниже плинтуса, если мерить миллиметры. (это тебе уже КиП изучать надо).

Считай в нанометрах мои инты, представляешь кактаващеда?, тоже будут подходить для всего.

считать долго.

Подели 1 на 3 и погляди точность, до этой точности он не будет плыть( прям как инт, представляешь?), а после неё будет плыть рандомно.

точность будет ровно 23 бита.

А теперь сравни с int:

1/3 == 0 | точность 0 бит
10/3 == 3| точность 2 бита
100/3 == 33| точность 6 бит
1000/3 === 333| точность 9 бит

Ты же только что идеализировал и говорил, что твои флоаты будет работать для всего?

ну они и работают для всего, со своей точностью. Например в 23 бита.

Ладно, дам подсказку: если при уровне 1м скорость воды 1л/с, то при уровне x метров, скорость x литров в секунду. Считай, что за время dt, скорость не меняется, потому-что dt маленькое. Например первые 500л вытекут за 500сек, а вторые 500л вытекут за 1000сек (ибо уровень вдвое меньше). Получается 1500сек. Теперь посчитай не по 500л, а скажем по 1литру (можешь юзать компьютер).

drBatty ★★
()
Ответ на: комментарий от unC0Rr

В твоём дабле он так же выходит за пределы и теряешь точность.

Ты можешь юзать пи в 40бит и получишь точность, которая даблу и не снилась, а 20бит тебе хватит обсчитать почти всё.

Вот, а точность с числами 20бит в дабле у тебя уйдёт в такую опу, что будет раза в 2 менее точно, чем в уинте64_т.

Считаешь в дабле тысячи? Получи точность 12знаков, миллионы? 9знаков. Дальше больше.

А в uint64_t ты берёшь пи в 40бит и спокойно считаешь миллиарды с точность не 6знаков, а овер12.

superhackkiller1997
() автор топика
Ответ на: комментарий от www_linux_org_ru

я, например, считаю, что в школе около 80% ненужного, при том, что закончил матмех с красным дипломом

- пишешь ты;

Это ясно любому более-менее вменяемому человеку

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

thesis ★★★★★
()
Ответ на: комментарий от drBatty

Это ОТВЕРСТИЯ, ОТВЕРСТИЯ. Глупая ты лалка. Если ты не понимаешь разницу между резом и сверлением( и то в 2-3прохода) - это твои проблемы.

ВНЕЗАПНО: мы в «цифровом» мире живём. В дискретном. Да, я понимаю, школьнику это учитывать совсем не нужно. Но знать уже пора-бы.

Лалка, ты несёшь такую херню - я просто не представляю. Мы живём не в дискретном мире - наше понимание мира дискретно.

Да, есть. Например в целых бутылках пива, действительно не бывает целой бутылки, полной чуть более, чем наполовину. Средняя погрешность целого числа == ½, а максимальная == 1.

Какая бутыл - ты что несёшь? Точность инста постоянна на всё его диапазоне значений - она идеальна и абсалютно точна.

шаг не рандомный, а вполне определённый. Погрешность — вполне определённая величина, измеряемая инженерами в долях или процентах, а программисты предпочитают двоичные логарифмы величины, которые называются «биты». НЁХ вполне можно взвесить и посчитать. Погрешность float равна 23 бита, а погрешность int зависит от величины этого int, и равна 1 единице младшего разряда. Вот та же рулетка даёт отличную точность, если мерить ей десятки метров, и точность ниже плинтуса, если мерить миллиметры. (это тебе уже КиП изучать надо).

Ай, ты слишком анскиллен чтобы с тобой говорить. Чё ты несёшь? Осиль флоат, а.

точность будет ровно 23 бита.

Ты что несёшь? Чего 23бита? С точность до единичного значения ты запишешь туда свои 23бита, а после тебя ждёт рандомное плытие.

А теперь сравни с int:

И что ты этим хочешь сказать? Точность инта будет такая, какую ты хочешь - хочшеь 23бита, как у флоата - юзай 23бита.

superhackkiller1997
() автор топика
Ответ на: комментарий от superhackkiller1997

В твоём дабле он так же выходит за пределы и теряешь точность.

ну ты возьми и попробуй. У нас не выходит, а у тебя — выходит.

Считаешь в дабле тысячи? Получи точность 12знаков, миллионы? 9знаков. Дальше больше.

понимаешь в чём проблема? Кроме сложения, есть и умножение. Перемножь в своём int'е несколько миллионов, и удивись.

Когда ты множишь и делишь числа, у тебя, в твоих int'ах наступает переполнение, и результат рандомный. А если ты захочешь делить и умножать, будет антипереполнение, и результат будет не 100метров, а скажем 10см. С float такого не бывает.

Есть ещё и третья беда: у тебя НЁХ в int неправильная, и результат ВСЕГДА меньше или равен истинному. Потому, даже если ты только складываешь, то результат у тебя падает с каждой итерацией в среднем на ½.

drBatty ★★
()
Ответ на: комментарий от AIv

Скажи мне во сколько раз твоё «решение» быстрее этого выхлопа.

float norm[4] = {1, 1, 1, 1}, xn[4] = {1, 1, 1, 1}; - это бусполезность мне можно выпиливать или как ты их собрался юзать?

У тебя на флоате НИКОГДА НЕ БУДЕТ точности 10знаков. НИКОГДА. Максимум, что ты можешь выжать это 6-7знаков с целой частью до 3-х знаков.

С каками x - расскажи мне.

superhackkiller1997
() автор топика
Ответ на: комментарий от superhackkiller1997

Это ОТВЕРСТИЯ, ОТВЕРСТИЯ. Глупая ты лалка. Если ты не понимаешь разницу между резом и сверлением( и то в 2-3прохода) - это твои проблемы.

ты упорот. Класс точности не зависит от того, отверстие это, вал, или линейный размер.

Лалка, ты несёшь такую херню - я просто не представляю. Мы живём не в дискретном мире - наше понимание мира дискретно.

ТВОЁ понимание не дискретно. На мир это никак НЕ влияет.

Какая бутыл - ты что несёшь? Точность инста постоянна на всё его диапазоне значений - она идеальна и абсалютно точна.

я уже заметил, сколько верных бит ты получил, разделив 1 на 3. Ровно НОЛЬ.

Ты что несёшь? Чего 23бита? С точность до единичного значения ты запишешь туда свои 23бита, а после тебя ждёт рандомное плытие.

23 бита — это логарифм. В привычных для тебя числах это ±0.000000059604644775390625 от размера самого числа (т.е. от двоичной экспоненты порядка, если быть точным).

И что ты этим хочешь сказать? Точность инта будет такая, какую ты хочешь - хочшеь 23бита, как у флоата - юзай 23бита.

я не хочу «точность, какую хочет superhackkiller1997», я хочу ГАРАНТИРОВАННУЮ ТОЧНОСТЬ. Не хуже, можно лучше.

drBatty ★★
()
Ответ на: комментарий от superhackkiller1997

Скажи мне во сколько раз твоё «решение» быстрее

ты сначала ПРАВИЛЬНОЕ решение получи. Потом поговорим, что там «быстрее».

С каками x - расскажи мне.

с любыми uint64_t ессно.

drBatty ★★
()
Ответ на: комментарий от drBatty

понимаешь в чём проблема? Кроме сложения, есть и умножение. Перемножь в своём int'е несколько миллионов, и удивись.

Перемножил милиард с милиардом. Твой дабл от милиона уже загнётся, а с милиардом просто фейланётся.

Когда ты множишь и делишь числа, у тебя, в твоих int'ах наступает переполнение, и результат рандомный. А если ты захочешь делить и умножать, будет антипереполнение, и результат будет не 100метров, а скажем 10см. С float такого не бывает.

Так же как и в твоих флоатах, только они не переполняются а начинают плыть.

Если юзать числа для которых дабл даст точность, то никогда ты не словишь переполнение.

Есть ещё и третья беда: у тебя НЁХ в int неправильная, и результат ВСЕГДА меньше или равен истинному. Потому, даже если ты только складываешь, то результат у тебя падает с каждой итерацией в среднем на ½.

Щито?

superhackkiller1997
() автор топика
Ответ на: комментарий от superhackkiller1997

-inf < x < 10 скажем. Одно из моих решений дает на даблах 12 знаков и требует порядка 100тактов для любых N больше 50ти. Попрубуйте сделать лучше, можете выпиливать и впиливать все что угодно.

AIv ★★★★★
()
Ответ на: комментарий от superhackkiller1997

Перемножил милиард с милиардом. Твой дабл от милиона уже загнётся, а с милиардом просто фейланётся.

перемножь 10^15 * 10^15. А float до 10^38 работает.

Щито?

того. Учи матчасть. После сложения двух Fixed Point, к ним надо прибавить половину младшего разряда. а ты думаешь почему У ТЕБЯ получается иногда 3.0000000, а иногда 2.9999999 ? Вот именно потому, что ты наивно думаешь, что НЁХ не бывает.

drBatty ★★
()
Ответ на: комментарий от drBatty

ты упорот. Класс точности не зависит от того, отверстие это, вал, или линейный размер.

Упоролся чтоли? Найди мне то, что решит до миллонных хотябы - я тебе дам флаг в руки. Класс точности зависит от вида обработки, глупая лалка.

я уже заметил, сколько верных бит ты получил, разделив 1 на 3. Ровно НОЛЬ.

Во флоате ты не делишь 1 на 3 - иди осилвай.

23 бита — это логарифм. В привычных для тебя числах это ±0.000000059604644775390625 от размера самого числа (т.е. от двоичной экспоненты порядка, если быть точным).

Да хоть хренагорифм. Как я и говорил после 23бит твоя точность - это порядки и то с шансом 50%. Т.е. точный счёт чего больше 23бит во флоате не имеет смысла, тогда зачем он нужен?

я не хочу «точность, какую хочет superhackkiller1997», я хочу ГАРАНТИРОВАННУЮ ТОЧНОСТЬ. Не хуже, можно лучше.

Гранатированная у тебя есть - это 64бита. Чем больше будут расти твои числа, тем больше она будет падать( так же во флоате).

Как я уже говорил, если ты боишься поймать переполнение, то ты множишь милиарды на милиарды, когда твой флоат поплывёт уже на сотнях милионов.

superhackkiller1997
() автор топика
Ответ на: комментарий от drBatty

перемножь 10^15 * 10^15. А float до 10^38 работает.

Точности не будет.

того. Учи матчасть. После сложения двух Fixed Point, к ним надо прибавить половину младшего разряда. а ты думаешь почему У ТЕБЯ получается иногда 3.0000000, а иногда 2.9999999 ? Вот именно потому, что ты наивно думаешь, что НЁХ не бывает.

Причем тут твои фикседпоинты? Я про них что-то говорил?

superhackkiller1997
() автор топика
Ответ на: комментарий от AIv

-inf < x < 10 в чем смысл юзать -inf, когда оно поплывёт и ты его обрежешь? Скажи вменяемые значения на которых твой дабл не плывёт, чтобы я знал.

Покажи выхлоп для твоих твоих предельных значений, пж.

superhackkiller1997
() автор топика
Ответ на: комментарий от superhackkiller1997

Упоролся чтоли? Найди мне то, что решит до миллонных хотябы - я тебе дам флаг в руки. Класс точности зависит от вида обработки, глупая лалка.

я тебе уже нашёл ссылку из учебника. Там миллионные доли метра. Это один маленький простой узел. Согласись, что весь девайс хотя-бы метровый? т.е. uint32_t явно мало, ибо танк явно больше 4х метров, а вот допуски там и поменьше микрона есть.

И да, класс точности зависит от назначения поверхности. Если это простая дырка для простого подшипника, то там обычно седьмой-восьмой класс точности. Т.е. доли микрона на миллиметры. Конечно, делаются такие дырки совсем не дрелью, тут ты прав.

Во флоате ты не делишь 1 на 3 - иди осилвай.

повторяю: точность в 32х битном float: 1/3=⅓±0.000000059604644775390625

И да, в современном CPU (не младше третьепня конца 90х), скорость обработки float ровно вдвое выше, чем 64х битных целых чисел. SSE жрёт их по 4 штуки сразу.

Да хоть хренагорифм. Как я и говорил после 23бит твоя точность - это порядки и то с шансом 50%. Т.е. точный счёт чего больше 23бит во флоате не имеет смысла, тогда зачем он нужен?

Очевидно для 99.9999% вычислений и нужен. Ибо такой точности всем хватает. Большая точность нужна только для каких-то особо сложных и точных расчётов, вроде расчётов положения планет (математики не осилили даже задачу трёх тел, потому приходится использовать пошаговое моделирование на многие миллиарды FlOps).

Гранатированная у тебя есть - это 64бита.

64 бита, только если в твоём int64 ВСЕ биты значимые. А вот например число 1 кодируется всего одним битом, и потому ½ считается со 100% ошибкой.

Чем больше будут расти твои числа, тем больше она будет падать

нет. В float ЛЮБОЕ валидное число записывается 23я битами. Например ⅛ == 100000000000000000000000₂ Т.е. 1 и ещё 23 нуля. ¼ записывается точно также. И 1048576 — монопенисуально. (т.к. первая цифра всегда 1, она никогда не хранится).

Как я уже говорил, если ты боишься поймать переполнение, то ты множишь милиарды на милиарды, когда твой флоат поплывёт уже на сотнях милионов.

никуда он не поплывёт.

drBatty ★★
()
Ответ на: комментарий от drBatty

я тебе уже нашёл ссылку из учебника. Там миллионные доли метра. Это один маленький простой узел. Согласись, что весь девайс хотя-бы метровый? т.е. uint32_t явно мало, ибо танк явно больше 4х метров, а вот допуски там и поменьше микрона есть.

Твой учебник говно. Ты понимаешь, что такое резка металла? Анскильная упорошка. ТЫ НЕ ПОЛУЧИШЬ БИЕНИЕ ПРИ КОТОРОМ У ТЕБЯ НА СРЕЗЕ ВОЛНЫ БУДЕТ В МИКРОНЫ.

Виды обработки, виды, глупое, анскильное ты лалка. Получают деталь с допусками в микроны ЛИШЬ ПОЛИРОВКОЙ.

И да, класс точности зависит от назначения поверхности. Если это простая дырка для простого подшипника, то там обычно седьмой-восьмой класс точности. Т.е. доли микрона на миллиметры. Конечно, делаются такие дырки совсем не дрелью, тут ты прав.

ЭТО СВЕРЛЕНИЕ, ПРИЧЕМ МНОГОПРОХОДНОЕ И ПОСЛЕДНИЙ ЭТАП ДАЛЕКО НЕ СВЕРЛО. У СВЕРЛЕНИЯ ТОЧНОСТЬ В ТЫСЯЧИ РАЗ БОЛЬШЕ, ЧЕМ У РЕЗА.

повторяю: точность в 32х битном float: 1/3=⅓±0.000000059604644775390625

Повторяю - точность это идеальная точность, а не допуск. Когда ты этой помёшь.

И да, в современном CPU (не младше третьепня конца 90х), скорость обработки float ровно вдвое выше, чем 64х битных целых чисел. SSE жрёт их по 4 штуки сразу.

Чё ты несёшь? Флоат - это тип, глупая ты лалка, а флоатпоинт. Дак 64битно целое число в 3раза точнее твоего флоата, не?

Очевидно для 99.9999% вычислений и нужен. Ибо такой точности всем хватает. Большая точность нужна только для каких-то особо сложных и точных расчётов, вроде расчётов положения планет (математики не осилили даже задачу трёх тел, потому приходится использовать пошаговое моделирование на многие миллиарды FlOps).

99.9999% вычислений влезет в uint64_t, но не влезет во флоат, а влезет в дабл.

64 бита, только если в твоём int64 ВСЕ биты значимые. А вот например число 1 кодируется всего одним битом, и потому ½ считается со 100% ошибкой.

Упоролся? Иди осиль целые числа и не неси херню. Умнож своё число на мильяр, потом дели. Ибо в uint64_t надо считать не целыми частями, а 1/100000000 представленной как один. Твой флоат делает это автоматом.

нет. В float ЛЮБОЕ валидное число записывается 23я битами. Например ⅛ == 100000000000000000000000₂ Т.е. 1 и ещё 23 нуля. ¼ записывается точно также. И 1048576 — монопенисуально. (т.к. первая цифра всегда 1, она никогда не хранится).

Не любое, а для которого во флоате есть диапазон. 3333333 - ты запишешь, выше у тебя случится фейл. и 333333333 == 333333339 и т.п.

никуда он не поплывёт.

Реально? Я тебе уже показал пи - оно поплыло.

float t = 0.987654321;
float t1 = 0.987654349;
if(t == t1) fprintf(stderr, "Токсичная пони - балабол\n"); 
//выхлоп: \
Токсичная пони - балабол

superhackkiller1997
() автор топика
Ответ на: комментарий от drBatty

и что ты этим хочешь доказать? Что другой порядок будет быстрее?

Что порядок вычисления, если и влияет на что-то, то на доли копейки; и что в 99% процентов вызовов оптимизатор может поменять порядок вычислений, не меняя семантики программы.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от drBatty

Ладно, дам подсказку: если при уровне 1м скорость воды 1л/с, то при уровне x метров, скорость x литров в секунду

Насколько я понимаю идею местного вундеркинда, предлагается считать в нанолитрах, нанометракх, наносекундак (или пико-). Точности int64_t всё равно хватит для всех практических задач.

tailgunner ★★★★★
()
Ответ на: комментарий от superhackkiller1997

Ок, ок, пусть -10<x<10, N=100. Пусть даже работа не с 4мя числами а с одним.

double superhackkiller1997_super_fail(double x){
    double xn = 1., res = 0., norm = 1.;
    for(int n=1; n<100; n++){
        norm *= n; xn *= x; res += xn/norm;
    }
    return res;
}
Хотя предполагается, что эта функция будет применяться к массиву, т.е. надо будет ее посчитать от большого числа разных х, но все они лежат в диапазоне [-10:10]. Мое решение стабильно дает 10ть знаков (для положительных х даже чуть больше, но это неважно).
х=10:   22025.4657948
x=-10: -0.99995460007
На моем стареньком Core 2Duo одно из моих решений (для обработки одного числа) занимает ~25 тактов на один вызов функции, это данные профилирования. Попробуйте обеспечить такую же точность для любого x из заданного диапазона и хотя бы не отстать.

Оченно ждем-с, думаю весь ЛОР замер в нетерпении.

AIv ★★★★★
()
Последнее исправление: AIv (всего исправлений: 1)
Ответ на: комментарий от superhackkiller1997

Микронной точности ты никогда не добьёшься в реальном мире. Это либо микроны на уровне микрон, либо такого не бывает.

Вау! Да месье у нас спец по обработке? Ну тады ой! Вот скажем при изготовлении зеркала телескопа (размер - метры, скажем метров пять, делается одним куском) допуски на изготовление 1/10-1/16 длины волны, т.е. десятки НАНОМЕТРОВ. Такие допуски тащем то при изготовлении любой хорошей оптики.

А при изготовлении камер токамаков допуски конечно побольше... но и сами камеры побольше;-)

В общем бывает в мире точность выше микронной на уровне МЕТРОВ. Потому как перед тем изготовлением это рассчитывают с точностью не меньшей чем допуск ес-но. Ну а про процессоры, у которых и точность и допуск 22нм при размере см как то и упоминать неловко...

AIv ★★★★★
()
Ответ на: комментарий от AIv

Оченно ждем-с, думаю весь ЛОР замер в нетерпении.

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

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

В воздухе стояла напряженная атмосфера ожидания чего-то эпохального...

Для продолжения отправьте SMS на короткий номер 02 с текстом "ya_lublu_programmirovat".
bk_ ★★
()
Ответ на: комментарий от AIv

На моем стареньком Core 2Duo одно из моих решений (для обработки одного числа) занимает ~25 тактов на один вызов функции

это с какими флагами и каким компилятором? я сейчас быстренько прикинул, у меня 22 такта занимает одна строка цикла, а не вся функция (g++ -O3; debian; AMD Phenom II X4)

#include <iostream>

inline double superhackkiller1997_super_fail(double x){
    double xn = 1., res = 0., norm = 1.;
    for(int n=1; n<100; n++){
        norm *= n; xn *= x; res += xn/norm;
    }
    return res;
}

int main() {
  double res=0;
  for( double x=-10; x<=10; x+=0.000001 ) {
    res += superhackkiller1997_super_fail(x);
  }
  std::cout << res;
  return 0;
}
www_linux_org_ru ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.