На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! правила раздела Алгоритмы
1. Помните, что название темы должно хоть как-то отражать ее содержимое (не создавайте темы с заголовком ПОМОГИТЕ, HELP и т.д.). Злоупотребление заглавными буквами в заголовках тем ЗАПРЕЩЕНО.
2. При создании темы постарайтесь, как можно более точно описать проблему, а не ограничиваться общими понятиями и определениями.
3. Приводимые фрагменты исходного кода старайтесь выделять тегами code.../code
4. Помните, чем подробнее Вы опишете свою проблему, тем быстрее получите вразумительный совет
5. Запрещено поднимать неактуальные темы (ПРИМЕР: запрещено отвечать на вопрос из серии "срочно надо", заданный в 2003 году)
6. И не забывайте о кнопочках TRANSLIT и РУССКАЯ КЛАВИАТУРА, если не можете писать в русской раскладке :)
Модераторы: Akina, shadeofgray
Страницы: (5) « Первая ... 3 4 [5]  все  ( Перейти к последнему сообщению )  
> Нецелая степень отрицательного числа
    Цитата Славян @
    Их же тупой интерпретатор вполне способен скушать десятичное представление числа в записи строки pow(-32,-0.2) (или как у них там?) и выдать норм ответ!?
    Разве Ява так делает? Да и не интерпретатор она.
    Или ты про ЯваСкрипт?
    Там просто в операциях требующих числа, строки неявно преобразуются в числа. С вполне себе двоичным представлением.

    Аппаратно архитектура i86 поддерживает двоично-десятичное представление.
    Среди основных команд процессора есть команды двоично-десятичной коррекции при сложении/вычитании (байтовые, медленные, остались от i8086/88, в котором они были нужны для совместимости с i8080/85).
    И среди команд арифметического сопроцессора есть команды чтения/записи чисел в двоично-десятичном представлении - 19 двоично-десятичных цифр в десяти байтах.
    Но внутри процессора все числа оббрабатываются в двоичном виде.
      Да просто подумалось, что встретив явную запись pow( -32, -0.2) интерпретатор (или как он там?) вполне мог бы осознать, что можно по-грамотному посчитать, и выдал бы результат. Хотя, таких случаев мало, существенно чаще есть pow(-32, x), а ужо 'x' где-то выше берётся. И тут - да, затык, ибо перевелось всё в двоичный вид. Печалька.

      Кстати, при разборе функции pow компилятор же мог бы умножать степень на нечётные числа и, в случае получения целого числа, мог бы сказать "ура! тут посчитается!" и посчитать. Или в этом направлении тоже есть изъян? Сходу пока не вижу.
        Цитата Славян @
        при разборе функции pow компилятор же мог бы умножать степень на нечётные числа и, в случае получения целого числа, мог бы сказать "ура! тут посчитается!" и посчитать.

        Даже если ты напишешь (-1.0/7.0) он не поймет, для него 7.0 !== 7, и после попыток вычислить аргумент он получит опять двоичное число...
          Да, так прямо не вышло, но зато вот как вышло! :
          ExpandedWrap disabled
            #include <stdio.h>
            main()
            {
                double a=2.0/17;
                for( int i=3; i<100; i+=2)
                {
                    double t = a*i - 2;
                    printf("test %g",t);
                    if( a*i!=double(2) ) printf(" %d:0\n",i);
                    else printf(" %d:1!\n");
                }
                printf("ok");
            }
          И вот вывод:
          ExpandedWrap disabled
            test -1.64706 3:0
            test -1.41176 5:0
            test -1.17647 7:0
            test -0.941176 9:0
            test -0.705882 11:0
            test -0.470588 13:0
            test -0.235294 15:0
            test -2.77556e-17 17:0
            test 0.235294 19:0
            test 0.470588 21:0
            test 0.705882 23:0
            test 0.941176 25:0
            test 1.17647 27:0
            test 1.41176 29:0
            test 1.64706 31:0
            test 1.88235 33:0
            test 2.11765 35:0
            test 2.35294 37:0
            test 2.58824 39:0
            test 2.82353 41:0
            test 3.05882 43:0
            test 3.29412 45:0
            test 3.52941 47:0
            test 3.76471 49:0
          Видим, что код вполне угадал число 17 - крохотная ошибка! :victory:

          Добавлено
          Слегка изменил код и произошло угадывание! :
          ExpandedWrap disabled
            double a=2.0/17;
                for( int i=3; i<100; i+=2)
                {
                    double t = fmod(a*i,1);
                    printf("\ntest %d: err=%g",i,t);
                    if( t!=0 ) printf(" -");
                    else printf(" +", i);
                }
          Вывод:
          ExpandedWrap disabled
            test 3: err=0.352941 -
            test 5: err=0.588235 -
            test 7: err=0.823529 -
            test 9: err=0.0588235 -
            test 11: err=0.294118 -
            test 13: err=0.529412 -
            test 15: err=0.764706 -
            test 17: err=0 +
            test 19: err=0.235294 -
            test 21: err=0.470588 -
            test 23: err=0.705882 -
            test 25: err=0.941176 -
            test 27: err=0.176471 -
            test 29: err=0.411765 -
            test 31: err=0.647059 -
            test 33: err=0.882353 -
            test 35: err=0.117647 -
            test 37: err=0.352941 -
            test 39: err=0.588235 -
            test 41: err=0.823529 -
            test 43: err=0.0588235 -
            test 45: err=0.294118 -
            test 47: err=0.529412 -
            test 49: err=0.764706 -
            test 51: err=0 +
            test 53: err=0.235294 -
          Оно же!??
            Ну, я такой алгоритм предлагал парой десятков постов выше. Работает, но полным перебором и может зациклиться (не остановиться).
              В общем, если такая функция нужна, то нет проблем её написать. Но пока я знаю только двух человек, которые ею заинтересовались. Причём подозреваю, если они её напишут, то после более тесного знакомства с нею они начнут ругать всех остальных здесь присутствующих за то, что те недостаточно активно их отговаривали от такого опыта.

              Такая функция выглядит неплохо в качестве умозрительных рассуждений или в качестве упражнения по программированию. В реальном коде она окажется источником плохо диагностируемых ошибок.
                А я вот сходу не вижу возможности написание оной за приемлемое для расчёта время. Как быстро "угадать", что знаменатель в несократимой дроби - нечётен? Непонятно. :-?

                Добавлено
                Впрочем, не, всё понятно. 10k раскладывается же на 2k*5k, а деление целого на 2 - тривиальная задача. Так что всё заработает весьма быстро. :yes:

                Добавлено
                Эх, в моём варианте функции (a'la double pow( double x, строка степень) ) всё равно не получится вычислить (-8)-1/3, ибо 1/3 запишется как 0.3333...333, а это означает, что равно 333...333/10k, а значит знаменатель - чётен. Проблема, блин. :wall:
                  Если пересмотреть формат хранения дробей, как двух целых - числитель и знаменатель, будет достаточно определить, что в числителе больше двоек-множителей, чем в знаменателе, то есть дробь сократима до нечётного знаменателя.
                    Да, согласен. Но вся беда в том, что для практического применения сей способ никак не годится. Ни за что (в практических целях) не будут вызывать функцию с числителем и знаменателем. Увы. А вот pow(-8, "0.(3)") ещё есть шанс, но тоже не ахти. Эх, не придумывается универсализм.
                      Цитата Mikle @
                      будет достаточно определить, что в числителе больше двоек-множителей, чем в знаменателе,
                      А не проще ли соератить дробь и посмотреть чётность знаменателя. Разложение на множители - довольно трудоёмкий процесс. Впрочем, максимальная степень 2 выделяется быстро.
                        Цитата amk @
                        А не проще ли соератить дробь и посмотреть чётность знаменателя. Разложение на множители - довольно трудоёмкий процесс.

                        В том то и дело, что полное сокращение не требуется, достаточно сократить двойки.
                        Цитата amk @
                        максимальная степень 2 выделяется быстро

                        Даже очень быстро, есть инструкция ассемблера, "bsf" или "bsr", не помню, ищет индекс первого справа установленного бита. Это и есть число двоек делителей.
                          Даже если такой инструкции нет, младший бит можно выделить выражением (n&-n)
                          0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                          0 пользователей:


                          Рейтинг@Mail.ru
                          [ Script execution time: 0,0408 ]   [ 15 queries used ]   [ Generated: 28.03.24, 10:47 GMT ]