LINUX.ORG.RU

рекурсия и итерация

 итерация,


1

3

Приветствую всех.
Вопрос мой довольно праздный, и возможно кому-то покажется бесполезным. Тем не менее. Не кажется ли вам, что то что сейчас понимается под этими 2 терминами несколько не соответствует действительности. Вот что я имею в виду. У нас есть рекурсивный процесс, он интуитивно понятен на примерах трельяжа, стихотворения «у попа была собака» и пр. В программировании он может быть выражен 2-мя способами: с помощью итерациии и с помощью того, что принято называть рекурсией
На концептуальном уровне, это, безусловно, неверно, поскольку мы имеем 1 процесс и 2 способа его реализации, и называть способ реализации процесса самим процессом не совсем правильно. Таким образом, я хочу сказать, что выражение «рекурсивная реализация алгоритма» значит то же, что «рекурсивная реализация рекурсивного алгоритма» - бессмысленный набор слов, и, при этом, сама реализация, собственно не имеет ничего общего с рекурсией
Хотелось бы попросить воздержаться от постов вроде «Ты не знаешь язык X и математическую теорию Y, поэтому ты чмо». Если то, что я написал кажется вам глупостью, просто проходите мимо.
Итак, ваши мнения, Господа.

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

да? Ну короче говоря я в курсе про GC без JIT, успокойся.

emulek
()
Ответ на: комментарий от Waterlaz

Вот и изучи. По _определению_ кольца (даже полукольца) умножение любых двух элементов этого кольца _определено_

ты пропустил слово «однозначно». Без него твоё «определение» не годно даже для того, что-бы им подтереться. Однозначно.

Ибо в противном случае верно, что 0/0==146%.

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

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

Это ты сам уже придумываешь.

А твоим «умножением» пользоваться нельзя, ибо его результат непредсказуем.

У меня все предсказуемо. Все математики пользуются - и у них тоже все предсказуемо. Может, дело не в умножении?

так и есть.

Нет, в кольце так не есть.

т.е. 2 умноженное на 1/2 получается то-ли 2, то-ли 7.

В Z_12 нету 1/2. Как ты собрался умножать на то, чего нет?

толку с этой изоморфности, если в кольце всё равно умножение не работает?

Во-первых умножение в кольце прекрасно работает. Во-вторых - умножение в кольце вычетов в точности совпадает с умножением в unsigned int. Так что оно или и там и там работает или и там и там не работает. Потому что это одно и то же умножение.

1. умножение без деления никому не нужно.

Нужно, представь себе.

2. деление в int таки определено. Что-бы ты там не говорил.

В int определено деление нацело. Деление, как операция обратная умножению - не определена, т.к. нету элементов обратных четным числам.

anonymous
()
Ответ на: комментарий от emulek

ты пропустил слово «однозначно».

Его все опускают, потому что оно всегда подразумевается. Но если хочешь - напишу явно. Умножение в кольце определено однозначно.

Потому что умножение в кольце - это, по определению, бинарная операция, а бинарная операция, по определению, должна давать однозначный результат.

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

На 2 в z_12 делить нельзя.

ага. А ещё на 0, на 1, на 3, на 4, и на 6. Классно!

Неоднозначно взятие обратного элементе. Не умножение.

само умножение неоднозначно. Т.е. умножать надо так, что-бы НЕ получилось {0,1,2,3,4,6,8,9,10}. И никак иначе!

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

нет. В int ты можешь выполнять операции с точностью до модуля. Т.е. это и не кольцо вычетов, и не поле Галуа(в поле Галуа GF(q^m)ты можешь умножать с точностью до q^n, где n — любое целое число)

Множество unsigned эквивалентно полю натуральных чисел, из которого вычеркнули все числа большие MAX_INT*2. Потому умножение там определено лишь для результатов И аргументов, которые внутри этого огрызка поля. Как и деление.

За пределами огрызка операции не определены.

А вычеты тут вообще не при чём. В вычетах не определено однозначно умножение, потому они не нужны в качестве int'ов.

emulek
()
Ответ на: комментарий от anonymous

В поле Галуа умножение тоже частично определено, но ПО ДРУГОМУ.

Любое поле является кольцом, в кольце умножение полностью и однозначно определено, поэтому определено и в любом поле, в том числе - в поле Галуа.

ты забыл, что у нас нет полей. Есть частный случай НЕ поля. Поле, которое с нулём. Для поля Галуа это тоже так. В нём однозначное умножение тоже частично определено, исключая 0. Для нуля однозначное умножение не определено.

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

само умножение неоднозначно.

Да где неоднозначно-то? Можешь привести хоть один пример?

Т.е. умножать надо так, что-бы НЕ получилось {0,1,2,3,4,6,8,9,10}. И никак иначе!

Да нет, почему? Пусть получается.

нет. В int ты можешь выполнять операции с точностью до модуля.

в unsigned int при переполнении берется остаток по модулю. и это ТОЧНО ТАК как ведут себя вычеты. приведи пример, где умножение unsigned int даст не тот же результат, что умножение в Z_(2^32)

Потому умножение там определено лишь для результатов И аргументов, которые внутри этого огрызка поля.

Да нет. Оно определено для всех элементов поля. Если происходит переполнение - берется остаток.

А вычеты тут вообще не при чём. В вычетах не определено однозначно умножение

Пример, пример. один пример - где умножение не определено (не деление, а умножение - то есть пример таких a и b что a*b = c1 и при этом a*b = c2), и второй - где инты ведут себя не так, как вычеты.

anonymous
()
Ответ на: комментарий от emulek

ы забыл, что у нас нет полей. Есть частный случай НЕ поля. Поле, которое с нулём. Для поля Галуа это тоже так. В нём однозначное умножение тоже частично определено, исключая 0.

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

Для нуля однозначное умножение не определено.

С чего вдруг? Если что-то умножить на ноль - это всегда ноль. Вполне однозначно. Сможешь опровергнуть контр-примером?

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

Ок. Алгебра, Ленг, страница 78.

нету под рукой.

Составил, воспользовался, какие проблемы?

проблема в том, что команда mul твоего CPU использует ДРУГУЮ таблицу умножения. В которой 2**8 получается таки 0 по модулю 256, а вовсе НЕ 29, как в поле Галуа. Причём это касается ВСЕХ чисел, за исключением степеней двойки меньше модуля.

Твоя проблема в том, что количество информации при умножении двух чисел УДВАИВАЕТСЯ, т.е. результат умножения двух чисел занимает вдвое больше бит. Потому обычное умножение НЕВОЗМОЖНО для чисел с фиксированной разрядностью(для любых таких чисел).

Однако, энтропия увеличивается не вдвое, а только на 1 бит. Потому-то можно переставить и поменять биты так, что-бы разрядность «умножения» не изменилась(не всегда. Для Z_12 нельзя). Вот только это будет совсем *другое* «умножение». Которое не имеет никакого отношения к вычетам.

Грубо говоря, при умножении двух отрезков x,y мы получаем отрезок равный x*y, в котором тем не менее полно дыр, которые никогда не получаются(например нет числа 11 среди всех произведений чисел от 0 до 9). И достаточно взять какую-то часть размера x+y, что-бы эти дырки убрать. Проблема только в том, что просто любой(или первый попавшийся, как вика рекомендует) отрезок НЕ подходит. Ибо дырки равномерно разбросаны по всему множеству x*y, а вовсе не гнездятся в его конце.

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

там другая проблема: Произведения двух вычетов ложатся только НА НЕКОТОРЫЕ точки. Т.е. у тебя на одно произведение приходится сразу несколько комбинаций вычетов. Точно также, как при умножении на ноль. При умножении на ноль ВСЕ точки обращаются в ноль. При умножении на многие вычеты МНОГИЕ РАЗНЫЕ числа дают ОДИН результат.

Т.е. неоднозначность тут как с единицами — 1*1*1*1*... И мы не знаем, СКОЛЬКО было единиц. Но единица — одна. А в вычетах таких «единиц» — МНОГО РАЗНЫХ. Потому с обычными числами неоднозначности и не возникает, т.к. нет разницы, сколько ЕДИНИЦ, ведь 1*1==1. Откуда 1==1*1*... И никак иначе. А вот с вычетами — беда. По твоим правилам получается только несколько произведений из всего множества, в которые и обращаются ВСЕ комбинации. Причём РАЗНЫЕ комбинации.

Ноль тут при том, что единица == это модуль в степени 0. Вот с ним и получается неоднозначность. Даже если этот модуль — бесконечный. Но эта неоднозначность ни на что не влияет, только где-то в бесконечности. Потому и int'ы хорошо работают, пока мы не приблизились к модулю.

emulek
()
Ответ на: комментарий от anonymous

Кольца классов вычетов - это в точности все факторкольца натуральных.

для сложения только. Потому-что кольцо != поле.

emulek
()
Ответ на: комментарий от anonymous

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

ты тоже забыл слово «однозначно».

И потом, дурак — ты. Да, над множеством вычетов по модулю чего-то можно построить поле. Да, там можно определить «умножение». Да, оно даже будет однозначным(если модуль q^m). НО! Кто тебе сказал, что это ТАКОЕ ЖЕ УМНОЖЕНИЕ как для целых? Википедики? Дык кто же изучает математику по википедии?

С чего вдруг? Если что-то умножить на ноль - это всегда ноль. Вполне однозначно. Сможешь опровергнуть контр-примером?

речь не про возможность, а как раз наоборот — про неоднозначность. Проблема не в отсутствии возможности, проблема в том, что их МНОГО. И они НЕОТЛИЧИМЫЕ. Особенно если твой модуль == произведение чего-то. Но даже если модуль == простое число, то даже в этом случае произведение получается однозначным только для бесконечности. Если это то самое произведение, которое в школе проходят, и которое в твоём компьютере.

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

Попробуй таки составить эту таблицу умножения

#include <cstdio>

int main() {
    const size_t n = 256;
    using byte = unsigned char;
    for (size_t x = 0; x < n; ++x)
        for (size_t y = 0; y < n; ++y)
#ifdef E
            printf("%lu * %lu = %lu\n", x, y, x * y % n);
#else
            printf("%hhu * %hhu = %hhu\n", byte(x), byte(y), byte(byte(x) * byte(y)));
#endif
}
➜  ~  cxx -DE z.cc && ./a.out > 1 && cxx z.cc && ./a.out > 2 && diff 1 2
➜  ~  

ЧЯДНТ?

Ну и деление — сишные / и % на вычетах вполне определяются, как и деление в вычетах на сишных числовых типах, просто это разные вещи.

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

нету под рукой.

А что по алгебре у тебя есть под рукой?

проблема в том, что команда mul твоего CPU использует ДРУГУЮ таблицу умножения. В которой 2**8 получается таки 0 по модулю 256, а вовсе НЕ 29, как в поле Галуа.

Ну ага, получается как в кольце вычетов. Это ты поля Галуа зачем-то притянул, а я тебе сразу сказал, что там умножение происходит совершенно по-другому. Более того, как-то адекватно ассоциировать с элементами поля Галуа (в отличии от вычетов) для степеней >1 натуральные числа вообще нельзя - т.к. это многочлены над вычетами.

Произведения двух вычетов ложатся только НА НЕКОТОРЫЕ точки.

Ну да. Как и у интов. Произведение от этого не становится неоднозначным.

Ноль тут при том, что единица == это модуль в степени 0. Вот с ним и получается неоднозначность. Даже если этот модуль — бесконечный. Но эта неоднозначность ни на что не влияет, только где-то в бесконечности. Потому и int'ы хорошо работают, пока мы не приблизились к модулю.

Какая неоднозначность? Ты так и не привел пример, где умножение вычетов неоднозначно.

anonymous
()
Ответ на: комментарий от emulek

для сложения только. Потому-что кольцо != поле.

Для всего.

anonymous
()
Ответ на: комментарий от emulek

ты тоже забыл слово «однозначно».

«однозначно» в этих определениях никто не говорит, потому что любую операция _по определению и так однозначна_. Незачем повторять одно и то же по нцать раз. Взятие обратного элемента - операция, по-этому она однозначна. Так что все прекрасно у нас с полями, есть они.

Да, над множеством вычетов по модулю чего-то можно построить поле.

Можно. Но не нужно.

Да, там можно определить «умножение»

Умножение определяется в любом кольце.

НО! Кто тебе сказал, что это ТАКОЕ ЖЕ УМНОЖЕНИЕ как для целых?

Оно такое же как для целых, если результат меньше модуля. Определение у него такое. умножение в кольце Z_n определяется как [x]*[y] = [x*y] mod n

речь не про возможность, а как раз наоборот — про неоднозначность.

Ну я у тебя и прошу привести пример неоднозначности. Найди мне такое число, которое, если умножить его на ноль, даст не ноль, нечто другое. Если таког очисла нет - то умножение на ноль - вполне однозначно, это ноль. ноль, ноль, и только ноль. Однозначно ноль. Как тебе еще объяснить?

anonymous
()
Ответ на: комментарий от emulek

Умножение определено лишь в бесконечном поле целых и вещественных чисел

В поле Галуа умножение тоже частично определено, но ПО ДРУГОМУ

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

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

ЧЯДНТ?

у тебя числа неравномерно раскиданы: на некоторые произведения приходится одна комбинация аргументов, а на другие — намного больше комбинаций. Т.о. твоё умножение неоднозначно. Что-бы оно стало однозначным, тебе нужно увеличить число бит произведения вдвое.

Ну и деление — сишные / и % на вычетах вполне определяются

я говорил о том, что нет однозначности. Если ты это считаешь «определением» — всё в порядке.

emulek
()
Ответ на: комментарий от anonymous

Более того, как-то адекватно ассоциировать с элементами поля Галуа (в отличии от вычетов) для степеней >1 натуральные числа вообще нельзя - т.к. это многочлены над вычетами.

числа — тоже многочлены: 123=10^2+2*10^1+3*10^0

Поля Галуа — тоже многочлены, да. Как и числа. Но другие.

Ну да. Как и у интов. Произведение от этого не становится неоднозначным.

увы. Становится. Одних нулей получается слишком много. Не дело это, когда умножение двух не нулей даёт нуль. Это нарушение логики. А всё равно, в int'ах sqrt(M)*sqrt(M)==0. Ну и других таких не однозначностей тоже много.

Какая неоднозначность? Ты так и не привел пример, где умножение вычетов неоднозначно

ну вот выше. Для uint8_t 16*16==0. Мало?

emulek
()
Ответ на: комментарий от anonymous

При чем тут вложение, если речь о включении?

при том, что вложение - это включение с точностью до изоморфизма

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

ты пропустил слово «однозначно». Без него твоё «определение» не годно даже для того, что-бы им подтереться. Однозначно.

в кольце однозначно определено произведение элементов

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

Всё. В не поле не определено умножение и деление. Оно не нужно на практике. В вычетах определено лишь сложение. (да и то со многими оговорками)

Прекращай. Ну зачем ты так упорно пишешь глупости и продолжаешь спорить?

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

сиё есть бред и мечта. Доказательство опубликовано Кнутом более 30 лет назад.

Дай ссылку. Мне действительно интересно, что конкретно Кнут доказал. Понятно же, что математический результат не может звучать как «GC сливает malloc/free»

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

Не понял. Пусть будет вообще не size_t, а неограниченный nat_t, считаем, что байт восьмибитный — берём все пары чисел (x, y) : nat_t * nat_t таких, что x и y < 256, и получаем x * y < 256 (операция из Z/256Z) для каждой пары как (x * y) % 256 (операции из N). Потом берём эти x и y и преобразуем в byte(x) и byte (y) (< 256, так что никаких переполнений), так что byte(byte(x) * byte(y)) даёт ровно то же число (< 256, тут нет переполнения — работает остаток от деления по модулю, ищи в стандарте си или плюсов по слову «modulo», например «Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2 n where n is the number of bits in the value representation of that particular size of integer.»), что и (x * y) % 256.

То есть структура <byte, operator+, operator-, operator*> изоморфна структуре Z/256Z.

Структура <byte, operator+, operator-, operator*, operator/, operator%> изоморфна Z/256Z на которой определены функциональные отношения целочисленного деления и остатка от такого деления (и если выкинуть ноль, то тотальные функциональные отношения, то есть функции).

Также, на Z/256Z определено функциональное отношение деления как обратной операции к функции умножения — оно же определяется и на byte, так что опять получается изоморфизм структур.

Итого, везде используются функции и функциональные отношения, то есть «_один_ результат» и, в случае функций, «целая область определения», то есть вполне «определено _однозначно_». Если считать, что «не определено _однозначно_» это «более _одного_ результат» (строго нефункциональное отношение), то тут такого нет.

Для беззнаковых типов другой битности — аналогично.

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

Я верю в тебя, бро. ты сможешь

anonymous
()
Ответ на: комментарий от quasimoto

тут нет переполнения — работает остаток от деления по модулю, ищи в стандарте си или плюсов по слову «modulo», например «Unsigned integers, declared unsigned, shall obey the laws of arithmetic modulo 2 n where n is the number of bits in the value representation of that particular size of integer.»

ты и ищи. Это и есть переполнение, которое ты не учитываешь. Потому у тебя ерунда и получается.

Итого, везде используются функции и функциональные отношения, то есть «_один_ результат

хрен с вами. Определили. Согласен. Теперь пользуйтесь своим «умножением», я не против.

emulek
()
Ответ на: комментарий от Waterlaz

Мне действительно интересно, что конкретно Кнут доказал. Понятно же, что математический результат не может звучать как «GC сливает malloc/free»

читай главу про менеджеры памяти. Она коротенькая.

emulek
()
Ответ на: комментарий от Waterlaz

в кольце однозначно определено произведение элементов

только там «умножение» хуже md5. Ибо md5 хотя-бы перебором можно обратить. А это твоё «умножение» НИКАК. Но я повторяю — это ваша проблема.

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

ты и ищи. Это и есть переполнение, которое ты не учитываешь. Потому у тебя ерунда и получается.

Ты тупой чтоли? Тебе специально, долбоебу, процитировали стандарт сишки, в котором сказано, что при переполнении результат считается modulo n^32

Что тебе еще надо, уебку?

anonymous
()
Ответ на: комментарий от emulek

Это и есть переполнение

Там дальше написано

This implies that unsigned arithmetic does not overflow because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting unsigned integer type.

И ещё

If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. [ Note: most existing implementations of C ++ ignore integer overflows.

В случае беззнаковых операции и mathematically defined, и in the range, причём mathematically defined они через shall obey the laws of arithmetic modulo 2^n (ну то есть вычеты, даже англоязычная вики про integer overflow упоминает про них).

З.Ы. http://stackoverflow.com/q/18195715

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

анончик, успокойся. Никто не обещал, что в сишечке ПОЛЕ. Или «кольцо вычетов». Нет там ни того, ни другого. А «по модулю» только сложение/вычитание.

emulek
()
Ответ на: комментарий от quasimoto

Это и есть переполнение, которое ты не учитываешь. Потому у тебя ерунда и получается.

ignore integer overflows.

кто из нас «тупой»?

В случае беззнаковых операции и mathematically defined, и in the range, причём mathematically defined они через shall obey the laws of arithmetic modulo 2^n (ну то есть вычеты, даже англоязычная вики про integer overflow упоминает про них).

и тем не менее, в кольце вычетов умножение не определено. А то, что у тебя, в русской вике «определено», — хрень полная. Не лезет произведение в такой же размер. Ему вдвое больше бит надо. В процессоре 8086 и выше, именно так и сделано. А в сишечке — обрезали. Получилась ерунда.

«Вычеты» определены для сложения. Оно да, по модулю 2*MAX_INT работает.

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

ignore integer overflows

Ну да, когда оно есть. А про беззнаковые числа сказано, что его нет, есть поведение арифметики по модулю — если результат (сложения, вычитания, умножения — http://stackoverflow.com/q/7221409, http://stackoverflow.com/q/9193880, http://en.cppreference.com/w/cpp/types/numeric_limits/is_modulo (!), http://www.cs.utah.edu/~regehr/papers/overflow12.pdf) не влезает, то берётся остаток от деления по модулю, в арифметике вычетов ситуация точно такая же — http://en.wikipedia.org/wiki/Modular_arithmetic#Integers_modulo_n (так же — сложение, вычитание, умножение).

в кольце вычетов умножение не определено

http://en.wikipedia.org/wiki/Modular_arithmetic#Integers_modulo_n [2]

Ну и если это кольцо, то как там может быть не определено умножение?

Не лезет произведение в такой же размер

Лезет оно — есть два числа < 2 ^ n, их результат тоже < 2 ^ n.

В процессоре 8086 и выше, именно так и сделано. А в сишечке — обрезали.

Вот и напиши сюда пример с imulq который бы вёл себя не так как умножение Z/(2^64)Z.

«Вычеты» определены для сложения

Если ты ок с тем, что max_unsigned + 1 = 0 это вполне себе «сложение» (но «не лезет» же), то умножение — тоже вполне себе «умножение». В любом случае, это всегда x # y = (x #N y) % (2 ^ n).

Оно да, по модулю 2*MAX_INT работает.

max_unsigned + 1 = 2 ^ n, если знаковые работают, то это будет 2 * (max_signed + 1) = 2 * |min_signed| = 2 ^ n — http://igoro.com/archive/why-computers-represent-signed-integers-using-twos-c....

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

и тем не менее, в кольце вычетов умножение не определено. А то, что у тебя, в русской вике «определено», — хрень полная. Не лезет произведение в такой же размер.

слова «в кольце X умножение не определено» не имеют смысла

умножение беззнаковых нормально работает

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

Ну да, когда оно есть. А про беззнаковые числа сказано, что его нет, есть поведение арифметики по модулю — если результат (сложения, вычитания, умножения

ну повторяю ещё раз: если есть переполнение (а в общем случае оно есть с вероятностью 4294967295/4294967296, т.е. практически 100%, при условии равномерного распределения аргументов), то результат умножения НЕ ОПРЕДЕЛЁН. То, что есть — как определение не годится, ибо является неоднозначным по аргументам. Это просто последовательность действий, которая даёт результат. И этот результат абсолютно бесполезен. Ну да, для фиксированных аргументов «произведение» однозначно. Может таки расскажешь, ЗАЧЕМ нужно это «произведение»? А то мне, IRL, приходится переходить к верхнему типу вроде uint64_t, что-бы туда загрузить произведение. А затем его оттуда по частям вынимать. Потому-что, даже если мне наплевать на точность, мне нужна *старшая половина*, а никак не младшая. Единственное, зачем нужна младшая — генерировать кривенькие псевдослучайные числа, в которых большая часть битов совсем не случайная, да и само число вполне себе предсказуемо. Есть ещё применения ЭТОЙ «арифметики»? Ну ты скажи, а то я не в курсе.

в кольце вычетов умножение не определено

http://en.wikipedia.org/wiki/Modular_arithmetic#Integers_modulo_n [2]

да. Есть «определение», но оно не годное. Если по твоему «годное», расскажи — для чего.

Ну и если это кольцо, то как там может быть не определено умножение?

однозначно не может быть определено. Куча эл-тов не имеет обратного эл-та по умножению. Т.е. эта твоя «определённость» напоминает дуршлаг. Грубо говоря, ты звонишь по телефону, и говоришь «я стою на дороге, и передо мной указатель „Москва -->“. ». Твоё местоположение определено? Таких указателей по России 100500. точно также и «определено» твоё «умножение».

Лезет оно — есть два числа < 2 ^ n, их результат тоже < 2 ^ n.

Иди в школу. 2^n * 2^n == 2^(2*n).

Вот и напиши сюда пример с imulq который бы вёл себя не так как умножение Z/(2^64)Z.

http://www.cs.cmu.edu/~fp/courses/15213-s07/misc/asm64-handout.pdf там ответ в %rdx:%rax. Т.е. биты с 64го по 127й лежат в %rdx. В сишечке они просто выкидываются.

И такая фигня ещё с i8086.

Если ты ок с тем, что max_unsigned + 1 = 0 это вполне себе «сложение» (но «не лезет» же)

лезет жеж! Никаких «дыр» нет в принципе, и единственная неоднозначность, которую мы имеем — один единственный бит (он связан с тем, что 2+7==7+2. Из за этого информация при сложении немножко теряется, потому-что работает переместительный закон, который и даёт неоднозначность. В итоге получается, что разрядность суммы на один бит больше). Но вот если одно из слагаемых фиксировано, и его энтропия равна нулю, то результат однозначный, т.е. энтропия не увеличивается. Например у increment'а 8и битного числа РОВНО 256 результатов, и КАЖДЫЙ из них ОДНОЗНАЧНО обращается. По этой причине, сложение определено ОДНОЗНАЧНО. В модулях — тоже. А вот умножение — увы.

то умножение — тоже вполне себе «умножение». В любом случае, это всегда x # y = (x #N y) % (2 ^ n).

это младшая половина результата. Кому и зачем она нужна — я не знаю. Лично мне приходится ограничиваться sqrt(M), в таком кусочке всё работает правильно.

max_unsigned + 1 = 2 ^ n, если знаковые работают, то это будет 2 * (max_signed + 1) = 2 * |min_signed| = 2 ^ n

я в курсе. К чему это ты?

emulek
()
Ответ на: комментарий от Waterlaz

слова «в кольце X умножение не определено» не имеют смысла

не «в кольце», а в вике. Там написано, что «определено», и это правда — _можно_ определить, например в поле Галуа. Или если у тебя результат не по модулю M, а по модулю M*M.

И да, сам подумай: если ты метры множишь на метры, то у тебя получаются в ответе *квадратные* метры. А почему модуль таким и остаётся? Какое ты имеешь право выносить модуль за скобки умножения?

умножение беззнаковых нормально работает

ну только в статье из википедии.

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

Какое ты имеешь право выносить модуль за скобки умножения?

лолшто?

умножение беззнаковых нормально работает

ну только в статье из википедии.

да нормальное там умножение по модулю.

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

Лично мне приходится ограничиваться sqrt(M), в таком кусочке всё работает правильно.

Т.е. ты развёл всю эту богодельню вот из-за этого правила, которое мне объясняли ещё на первом курсе, когда в школе даже не знали слова «информатика»?

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

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

Т.е. ты развёл всю эту богодельню вот из-за этого правила, которое мне объясняли ещё на первом курсе, когда в школе даже не знали слова «информатика»?

ну типа да.

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

удивительно то, что 95% этого правила всё равно никогда не поймут... И будут искренне уверены, что их няшный питончик таки считает «правильно». Вот и вика тоже — гарантирует...

PS: шутка удалась лишь на 10й странице. Печально... Лет десять назад меня-бы поймали в 10 раз быстрее... Куда катится мир?..

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

И будут искренне уверены, что их няшный питончик таки считает «правильно».

А в питоне при «переполнении» разве автоматически не возвращается ответ в «больших числах»? Или это я по лиспу теперь всю динамику сужу? )))

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

Какое ты имеешь право выносить модуль за скобки умножения?

лолшто?

данишо. Не лолкай, лоли. Иди лучше в школу, спроси училку про модули, она объяснит. А вику больше не читай. Это энциклопедия, а не учебник.

да нормальное там умножение по модулю.

детка, компьютер нужен для обработки информации. Инструменты этой обработки называются «операторами». В них не должно быть дырок, а если они есть, их должно быть немного, что-бы можно было их затыкать. Т.е. оператор не должен быть решетом, которое в принципе не заткнуть. Т.е., если информация даже теряется, то надо ТОЧНО знать, КАК, КОГДА, и СКОЛЬКО. Вот в твоём «умножении» теряется ПОЛОВИНА результата, потому оно годно лишь для создания кривого рандома. И кривой он кстати как раз именно из-за этих потерь. Даже самый лучший генератор ПСЧ из 32х бит теряет 99.6% случайности. Т.о. оно даже для рандома не годно.

emulek
()
Ответ на: комментарий от yyk

А в питоне при «переполнении» разве автоматически не возвращается ответ в «больших числах»?

ой, да. Это я ошибся — вот питон как раз возвращает. Мой даже 2**128 посчитал. Т.ч. там нормальная арифметика.

emulek
()
Ответ на: комментарий от Waterlaz

тащем-то, всё, что я выше написал, остаётся в силе. Если ты не понял, то замечание про корень из модуля ничего не меняет, и тащем-то я его сам и привёл. Ибо надоело мне над вами издеваться, детки...

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

тащем-то, всё, что я выше написал, остаётся в силе. Если ты не понял, то замечание про корень из модуля ничего не меняет, и тащем-то я его сам и привёл. Ибо надоело мне над вами издеваться, детки...

как же ты уныл. Ты писал бред. Каждое второе твое утверждение показывает, как мало ты понимаешь в том, что пишешь.

Считай, что ты вышел на улицу и голой жопой сел в лужу. Люди покрутили у виска и пошли дальше. Думаешь, что это ты так над кем-то поиздевался? Ок, продолжай думать, если тебе так проще.

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

Короче, вопрос терминологии. Ты считаешь, что (арифметическая, надеюсь) функция «однозначно определена» только когда это функция-биекция. Для меня определённость это «просто последовательность действий, которая даёт результат», то есть функция. Или надо явно говорить «не определена обратная», «не биекция».

В случае вычетов, как минимум:

1. Любая f : ℤ × ℤ → ℤ со свойством ∃ n f₁ f₂. ∀ a b k l. f(a + k * n, b + l * n) = f₁(a, b, n) + f₂(a, b, k, l, n) * n обобщается с ℤ на ℤ/nℤ как f′ : ℤ/nℤ × ℤ/nℤ → ℤ/nℤ; f′([a], [b]) = [f₁(a, b, n) % n].

2. ⟨ℤ/nℤ, f′⟩ ≊ ⟨n ‌? [0, n) : ℤ, λ a b → f₁(a, b, n) % n⟩.

3. «Обобщается», так как при n = 0 получаем ℤ/0ℤ ≊ ℤ, f = f₁, f′([a], [b]) = [f(a, b)], ⟨ℤ/0ℤ, f′⟩ ≊ ⟨ℤ, f⟩.

4. +, ─ и * обладают свойством (1), так что ⟨ℤ/nℤ, +′, ─′, *′⟩ ≊ ⟨n ? [0, n) : ℤ, λ a b → (a + b) % n, λ a b → (a ─ b) % n, λ a b → (a * b) % n⟩.

2^n * 2^n == 2^(2*n).

Так мы в вычетах умножаем или где? «< 2 ^ n», ну и % (2 ^ n) на результате делать нужно, либо сдвигать на n.

В сишечке они просто выкидываются.

Что эквивалентно сдвигу, что эквивалентно взятию остатка по модулю от результата, то есть относительно {8, 16, 32, 64}-битных регистров мы получаем в точности умножение ℤ/(2^{8, 16, 32, 64})ℤ. А то речь шла про «это не вычеты» и «в вычетах нет умножения».

К чему это ты?

Опечатка у тебя там была.

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

детка, компьютер нужен для обработки информации. Инструменты этой обработки называются «операторами». В них не должно быть дырок, а если они есть, их должно быть немного, что-бы можно было их затыкать. Т.е. оператор не должен быть решетом, которое в принципе не заткнуть. Т.е., если информация даже теряется, то надо ТОЧНО знать, КАК, КОГДА, и СКОЛЬКО. Вот в твоём «умножении» теряется ПОЛОВИНА результата, потому оно годно лишь для создания кривого рандома. И кривой он кстати как раз именно из-за этих потерь. Даже самый лучший генератор ПСЧ из 32х бит теряет 99.6% случайности. Т.о. оно даже для рандома не годно.

Оно очень даже годно. Если я знаю, что результат помещается в мой беззнаковый тип, то я могу не переживать, что в промежуточных результатах где-то будет переполнение. У меня гарантированно будет правильный ответ.

Где-то так:

unsigned char a = 150;
unsigned char b = 210;
unsigned char r = 15*b-20*a
Waterlaz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.