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

    Получается, что если основание степени X отрицательное, а показатель Y нецелый, значит нужно найти P и Q, такие, что Y=-P/Q. И если Q - чётный, значит облом. Если нечётный, значит ответом будет -(Sqrt_Q(X))^P. В нашем случае можно сделать проще: -(|X|^Y).
    К примеру, имеем -3/7, представленное числом конечной точности -0.428571428571429.
    Как найти P=3 и Q=7 ???

    Добавлено
    Если |Y|>1 то можно сделать так: V=Trunc(|Y|), W=Frac(|Y|), XY=-XV*XW, если, конечно, W будет представлено как P/Q, где Q нечётное.
    Я к тому, что возможно, W=Frac(|Y|) будет легче разложить на P и Q (W=P/Q).
      Подбор оптимальной дроби под вещественное число - широко же известная задача, и, сколько помнится, вполне неплохо решённая. Что-то с цепными дробями там было. Надо рыть... :scratch:
        По логике это делается так:
        0.2 = 2/10, находим НОД(2,10)=2, делим 2 и 10 на 2, получаем 1 и 5, т.е. P=1, Q=5.
        0.25 = 25/100, находим НОД(25,100)=25, делим 25 и 100 на 25, получаем 1 и 4, т.е. P=1, Q=4.
        3/7 = 0.4285714285714 = 4285714285714/10000000000000, находим НОД(4285714285714,10000000000000)=2, делим на 2, получаем P=2142857142857, Q=5000000000000, но это явно не 3 и 7... аналогичная история будет с 1/3.
        Что делать?
          Во, точно: wiki: Цепная дробь - Приближение вещественных чисел рациональнымих
          Цитата
          Цепные дроби позволяют эффективно находить хорошие рациональные приближения вещественных чисел.
            Если взять 0.428571428571429, то 1/0.428571428571429 = 2.33333333333333. Если вычесть 2, то получим 0.333333333333333 и далее 1/0,333333333333333 = 3. Вот вам и 3/7. Но это я вычислил вручную.
            Если взять 1764/7463, то так уже не прокатит.

            Славян, ща гляну :)
              Цитата Jin X @
              Как пишет Википедия, "корень нечётной степени из отрицательного числа — отрицательное число, однозначно определенное".
              Т.е. получается, например, (-32)-0.2=-0.5 или (-10)-3/7.

              Эммм... а с каких пор -0,2 и -3/7 стали НЕЧЁТНЫМИ?
              Что же до переноса на
              Цитата Jin X @
              Получается, что если основание степени X отрицательное, а показатель Y нецелый, значит нужно найти P и Q, такие, что Y=-P/Q. И если Q - чётный, значит облом. Если нечётный, значит ответом будет -(Sqrt_Q(X))^P. В нашем случае можно сделать проще: -(|X|^Y).

              то он неоднозначен. Ибо никто не отменял того, что -0,2 = -1/5 = -2/10, или что -3/7 = -6/14. А объявлять, что равенство -0,2 = -1/5 более истинно, чем равенство -0,2 = -2/10 есть нонсенс.

              Добавлено
              Цитата Jin X @
              Если взять 1764/7463, то так уже не прокатит.
              Дык это просто точности поди не хватит потому что...
                Akina, можно просто расширить класс нечётных чисел до:
                Цитата
                Нецелое рациональное число q назовём Нечётным, если в несократимой дроби для q нечётным является знаменатель.
                и т.о. пытаться извлекать корень из нечётных рациональных. :)

                Добавлено
                Имелось ввиду: и будем пытаться извлекать корень рациональной "нечётной" степени из отрицательных.
                  Цитата Славян @
                  можно просто расширить класс нечётных чисел до:

                  Такое расширение работает только на подмножестве несократимых дробей и, следовательно, неприменимо ко всему классу дробей.
                  Тогда уж куда как разумнее перейти к вычислению нецелых степеней в пространстве комплексных чисел на подмножестве результатов с нулевой мнимой частью...
                    Цитата Akina @
                    Такое расширение работает только на подмножестве несократимых дробей и, следовательно, неприменимо ко всему классу дробей.

                    Дружище, ты не прав!

                    Для того, чтобы мочь не получить комплексное число при возведении в степень отрицательного числа в дробную степень - нужно три условия:

                    1) Если степень - дробь, то она должна быть несократимая (или - сокращать, а что такое "подмножество сократимых дробей"? дай пруф)
                    2) Четность или нечетность рассматривается только для знаменателя дроби степени (ибо только знаменатель отвечает за кратность извлекаемого корня)
                    3) Для иррациональных чисел данный подход не использовать под страхом стерилизации
                      Цитата JoeUser @
                      а что такое "подмножество сократимых дробей"?

                      Ясен пень, всё множество дробей за вычетом дробей несократимых. Как я понимаю, по вопросу определения этих двух подмножеств у тебя никаких проблем нет...
                        Цитата Akina @
                        проблем нет...

                        Есть чисто теологические. Вернее научно-общепринятые научными учеными от математики :lol:
                        Akina, "множество сократимых дробей" и "множество несократимых дробей" в математике должно где-то обозначаться, фигурировать. Если это не собственный креатив. Давай обозначим тематику - где эти термины используются? Работы/источники/учебники/монографии? Чисто чтобы заценить "не локальность терминов", а их глубину глубин.
                          Цитата JoeUser @
                          "множество сократимых дробей" и "множество несократимых дробей" в математике должно где-то обозначаться, фигурировать. Если это не собственный креатив.

                          Насколько я понимаю, именно этот "креатив" (если, конечно, принять на веру утверждение, что не существует дробей, не относящихся ни к одному из этих подмножеств) и породил собственно сию тему. Ну может плюс утверждение, что любое вещественное число может быть приближено дробью с любой заданной точностью.
                            Сократимые и несократимые дроби, это всего лишь выбор числителя и знаменателя. Число, обозначаемое 2/3 или 4/6 остаётся одним и тем же, никакого особого математического смысла эти обозначения не несут (кроме того, что числом 2/3 проще оперировать, чем, скажем, 117197488/175796232). Так же десятичные дроби 0.6(0) и 0.5(9) обозначают одно и то же число, просто приняли соглашение, что для записи числа 3/5 используется первое обозначение, а не второе.

                            Цитата JoeUser @
                            "множество сократимых дробей" и "множество несократимых дробей" в математике должно где-то обозначаться, фигурировать.
                            Не существует множеств сократимых и несократимых дробей. Есть множество рациональных чисел, обозначаемое особо символом ℚ. А будешь ты использовать для их обозначения: сократимые или несократимые дроби, разложение в сумму аликратных, десятичные с периодом, или найдёшь ещё какой-нибудь удобный тебе способ их записывать, это твоё личное дело, и не надо свои предпочтения навязывать окружающим.

                            И вообще, думаю, эта тема скоро превратмтся (или уже превратилась) в очередной холивар.

                            Добавлено
                            Цитата Akina @
                            утверждение, что любое вещественное число может быть приближено дробью с любой заданной точностью
                            Можно ещё вспомнить теорему "Множество рациональных чисел всюду плотно"
                            Сообщение отредактировано: amk -
                              Цитата Akina @
                              Эммм... а с каких пор -0,2 и -3/7 стали НЕЧЁТНЫМИ?

                              Там же "корень", т.е. x^(-3/7) = (x^(1/7))^(-3) и вот в скобках корень нечетной степени. 0.2 это 1/5, в знаменателе нечетное число, значит, можно вычислить через корень нечетной степени.
                              Цитата Jin X @
                              К примеру, имеем -3/7, представленное числом конечной точности -0.428571428571429.
                              Как найти P=3 и Q=7 ???

                              Складывать само с собой, пока не получится результат, у которого дробная часть отличается от нулевой нв невеликое по отношению к единице число. Сколько раз сложили, это Q, какая получилась целая часть, это Р. "Невеликость" определяется известной точностью исходного числа, разница должна быть по модулю меньше, чем Q*эпсилон.
                                Цитата Vesper @
                                Там же "корень", т.е. x^(-3/7) = (x^(1/7))^(-3) и вот в скобках корень нечетной степени.

                                Честнее написать x^(-3/7) = (x^(N/7))^(-3*N), где N - натуральное. И нечётность корня как-то сразу поплыла...
                                  Цитата Akina @
                                  Насколько я понимаю, именно этот "креатив" (если, конечно, принять на веру утверждение, что не существует дробей, не относящихся ни к одному из этих подмножеств) и породил собственно сию тему. Ну может плюс утверждение, что любое вещественное число может быть приближено дробью с любой заданной точностью.

                                  Ланна. Давай более предметно. К примеру, "вещественные числа" уже есть в обиходе, и это есть общедоступный математический инструмент.
                                  А что есть в математике, и где есть "подмножество несократимых дробей"??? Имя термина???

                                  Цитата Akina @
                                  Ясен пень, всё множество дробей за вычетом дробей несократимых. Как я понимаю, по вопросу определения этих двух подмножеств у тебя никаких проблем нет...

                                  Интуитивно "да". Но для введения своих даже интуитивно-понятных терминов в арсенал математики - нужно быть как минимум Перельманом Гришей.
                                    Цитата JoeUser @
                                    А что есть в математике, и где есть "подмножество несократимых дробей"??? Имя термина???
                                    Ты не читаешь, что тебе пишут. В математике нет ни множества, ни подмножества "несократимых дробей". Соответственно нет и термина для такого несуществующего "множества".
                                    Дробь это вообще не само число, а только способ его записи. Числа, которые можно получить как отношение двух целых чисел называются рациональными и они не бывают сократимыми или несократимыми. Ясно, что для каждого такого рационального числа пар таких существует бесчисленное множество, но среди них есть только одна, в которой числитель и знаменатель не имеют общих множителей (отличных от 1), и знаменатель положителен.
                                      Цитата amk @
                                      Ты не читаешь, что тебе пишут. В математике нет ни множества, ни подмножества "несократимых дробей". Соответственно нет и термина для такого несуществующего "множества".

                                      Как раз это я и пытаюсь показать.

                                      Цитата JoeUser @
                                      Akina, "множество сократимых дробей" и "множество несократимых дробей" в математике должно где-то обозначаться, фигурировать. Если это не собственный креатив.

                                      Так кто из нас не читает? :lol:
                                        JoeUser
                                        Понятие введено тут: Нецелая степень отрицательного числа (сообщение #3755291)
                                        И не мной.
                                        Поскольку оно "интуитивно понятно" - я им воспользовался.
                                          Цитата Vesper @
                                          Складывать само с собой, пока не получится результат, у которого дробная часть отличается от нулевой нв невеликое по отношению к единице число. Сколько раз сложили, это Q, какая получилась целая часть, это Р. "Невеликость" определяется известной точностью исходного числа, разница должна быть по модулю меньше, чем Q*эпсилон.
                                          Ага, и какова будет скорость работы такой функции? В случае, если Q = 1E15, например... :)

                                          Akina, amk, к чему вы клоните? К тому, что (-32)-0.2 не существует и не равно -0.5 ?
                                          А что скажете про это?
                                          Цитата
                                          По определению, ap/q=sqrt_q(a)p, pϵZ, qϵN
                                          Результат не определён при a=0 и p/q<=0
                                          Для отрицательных a в случае нечётного p и чётного q в результате вычисления степени получаются комплексные числа.


                                          Добавлено
                                          Текст "в случае нечётного p и чётного q" в моём понимании означает, что 6/14 нужно сократить до 3/7, а 6/16 сократить до 3/8 (чтобы либо p, либо q стало нечётным). Тогда станет понятно – комплексные числа получатся или действительные...
                                            Цитата Jin X @
                                            к чему вы клоните? К тому, что (-32)-0.2 не существует и не равно -0.5 ?

                                            Ну можно поёрничать насчёт того, что всё-таки минус два, а не минус половинка. Но это так...

                                            А если по делу - то формально имеется 5 различных значений (-32)-0.2, одно из которых равно -2, а остальные комплексные. И отфонарный выбор одного из этих значений как "более правильного" мне как раз и не нравится.

                                            Добавлено
                                            Цитата Jin X @
                                            Текст "в случае нечётного p и чётного q" в моём понимании означает, что 6/14 нужно сократить до 3/7

                                            Мне не нравится слово "нужно". Не вижу никакого обоснования нужности этого действия.
                                              Цитата Akina @
                                              ожно поёрничать насчёт того, что всё-таки минус два, а не минус половинка.
                                              Ну-ка, попробуйте! А ещё скажите тогда чему равно (-32)0.2 ?.. :whistle:
                                                Цитата Славян @
                                                Ну-ка, попробуйте!

                                                Ну не получилось... бывает.
                                                  Этот спор имеет смысл только в случае именно рациональных показателей. Как правило запись 0.2 в математике, если не оговорено особо, означает, что значение может изменяться от 0.15 до 0.25 включительно, и может принимать, в том числе, и любое иррациональное значение на этом интервале.
                                                  Цитата Jin X @
                                                  Akina, amk, к чему вы клоните? К тому, что (-32)-0.2 не существует и не равно -0.5 ?
                                                  Лично я клоню к тому, что это значение существует, но утверждать, что оно равно -0.5 не вполне корректно.
                                                  Даже в случае рационального показателя 1/5 в комплексной области существует целых пять значений. Не знаю, заметил ли ты, что замена 1/5 на 2/10, 3/15 или любую другую дробь с тем же значением количество значений не увеличивает, подозреваю, что не обратил внимания. То есть число возможных значений равно знаменателю дроби представляющей показатель после её сокращения.
                                                  Если основание положительно, то по крайней мере одно из значений будет вещественным, не зависимо от чётности знаменателя, при чётном знаменателе их два - одно положительное, другое отрицательное, при нечётном - только оно положительное.
                                                  Если основание отрицательно, то при нечётном знаменателе по-прежнему будет одно вещественное значение, на этот раз отрицательное, а при чётном все значения окажутся комплексными.
                                                  А теперь перейдём к более интересному случаю - пусть показатель у нас будет не обязательно рациональным. При иррациональном показателе в случае положительного основания по-прежнему есть одно положительное вещественное значение, и бесчисленное множество иррациональных значений, равномерно и плотно распределённых по окружности с центром в нуле. А в случае отрицательного основания значений так же бесконечно много, они так же равномерно плотно расположены по окружности, и ни одно из них не является вещественным. Славян, согласись, работать с бесконечными множествами значений как-то некомфортно. Поэтому решили выделить какое-то одно, ведущее себя более менее предсказуемо. Одно из таких значений, пользующееся наибольшим спросом, - это положительное вещественное значение при положительном основании.
                                                  Все остальные слишком зависят от ситуации.

                                                  Так что, если тебе надо, определяй конкретное значение из имеющихся так, как тебе надо. Но это будет не универсальным решением. Но это будет решение, подходящее для конкретной задачи. Скорее всего, уже в следующей задаче тебе понадобится определять степень новым способом.
                                                    Цитата amk @
                                                    Как правило запись 0.2 в математике, если не оговорено особо, означает, что значение может изменяться от 0.15 до 0.25 включительно, и может принимать, в том числе, и любое иррациональное значение на этом интервале.

                                                    Шта? :blink:
                                                      Цитата amk @
                                                      это будет решение, подходящее для конкретной задачи
                                                      Смотри. По поводу конкретной задачи. Эта тема плотно связана вот с этой и где-то является её продолжением. Только там речь про 00, а тут про другие основания и показатели степени. Но всё сводится к тому, что это всё нужно для того, чтобы найти значение, которая будет возвращать функция Power.
                                                      Т.е. если задать функции значения -32 и -0.2, каков результат должен быть? -0.5 или NaN? Проще выдавать NaN, но мне кажется, что это халтура.
                                                      Далее, а если показатель степени будет -0.428571428571429? То каков должен быть результат -Sqrt_7(32)3?
                                                      Или лучше написать отдельную функцию, которая будет принимать в качестве аргументов 3 значения: X, P и Q и в случае отрицательного X и [нецелого P или нецелого Q или чётного Q] посылать всех в чертям (даже не пытаясь упростить эту дробь)?
                                                      Есть ещё вариант. В той теме описана функция FastPowerECB (с callback'ом в случае ошибки). Может, специально для неё написать callback-функцию, которая будет пытаться найти P и Q и выдавать не NaN, а отрицательное вещественное число?
                                                        Цитата amk @
                                                        Славян, согласись, работать с бесконечными множествами значений как-то некомфортно. Поэтому решили выделить какое-то одно, ведущее себя более менее предсказуемо. Одно из таких значений, пользующееся наибольшим спросом, - это положительное вещественное значение при положительном основании.
                                                        Весьма условно соглашусь. А именно: возведение в степень - бесконечнозначное отображение, как изучается в ТФКП. Поэтому можно считать, что pow(a,b) это в программировании Re(ab). А тогда получим, что при целом показателе ветви все склеятся в одну, а в рациональном - получится столько, каков знаменатель в несократимой дроби того рационального числа. В иррациональном же случае ни один лист не даст вещественное, но зато будут существовать чисто мнимые значения, а потому вполне логично вернуть 0. :rolleyes:

                                                        Добавлено
                                                        Впрочем, у программистов иррациональных чисел не бывает, а потому надо тщательно исследовать какое рациональное пришло в показателе степени - "чётное" (знаменатель несократимой дроби) или нет. Стандартом, думаю, предполагается, что все они, увы, чётные.
                                                          вот поэтом у я с опаской отношусь к чужим программам, пока досконально их не проверю. Неизвестно какие тараканы в голове у их авторов ползают.
                                                            В итоге, хоть я и накрутил с этими Re, ваша мысль, amk, всё равно качественно правильнее: есть вагон значений и из него пожелали люди выбрать такое-то (то положит, то отрицат, то чисто мнимое). Хотя если в этой глупой Яве[ЯвеСкрипт] число 0,2 хранится именно в таком, честном, виде, то им следует всё же вернуть -1/2 на (-32)-0.2. Однако как это узнать - понятия не имею, ведь даже если в Си написать:
                                                            ExpandedWrap disabled
                                                              float a=0.2f;
                                                              if( a==0.2f )

                                                            то будет же истина, хотя в машине это и не будет честным 0,2 а станет каким-то 0,2000000000000001325 или нечто такое. Печаль, короче, какая-то. Implem... Spec... или как там Qraizer выражается...
                                                              Парни, признайтесь, что это все стеб! >:(

                                                              Я читаю, и у меня из глаз льется кровь! Что такое "отрицательная степень", что такое "дробная степень" все же знают? Все знают как меняется знак от четности/нечетности возведения в степень, все знают что можно извлекать корень нечетной степени из отрицательного числа не уходя в комплексное исчисление? Нафига все эти домыслы?!!! Неужели курса математики старших классов мало???! :blink:
                                                                Эх, Joe, joe... Изъян же, сами видите, в том, что не все компиляторы тянут норм. ответ. Да и не только компиляторы!! У меня вон плагин в FAR'е не хочет считать (-32) pow (-0.2). А корень мы берём не из нечётной, а из дробной (нецелой) отрицательной! А там - ворох проблем, создающих тему.
                                                                  Цитата Славян @
                                                                  А корень мы берём не из нечётной, а из дробной (нецелой) отрицательной!

                                                                  Ну так а что меняется, если приходится сочетать условия?
                                                                    Славян, напиши себе свою функцию возведения в степень. И не будет нужды уому-то что-то доказывать.
                                                                    Ты же не программистом работаешь, тебя за использование велосипедов наказывать не будут?
                                                                      Да не я ж темы создавал. Мне особо и не надо. Когда надо - знаю как считать. Так что проблем моих тут нет.
                                                                      Вот, эксперимента ради, установил какой-то Перл только что. Он не захотел даже считать $x = (-32)**(0.2), написав -1.#IND
                                                                      Так просто хочется проверить, что у Joe правильно тогда минус скушался...

                                                                      Добавлено
                                                                      Вот и верь после этого людям... Тьфу, т.е. Перлам! :jokingly:
                                                                        Цитата Славян @
                                                                        Вот и верь после этого людям... Тьфу, т.е. Перлам!

                                                                        Я же на онлайн компайлер давал ссылку! Там все считалось норм. Ты наверное что-то не то установил.
                                                                          Да наверное не то. Но всё же пусть микро, но камешек в огород! Тогда не считало (2009 года perl.exe), а тут начало считать! Якобы математика поменялась! Ишь!! :-)
                                                                          Эх, прогеры, прогеры...
                                                                            Версию поменяли, осознали свою неправоту. Каждый имеет право на ашыпку! :lol:
                                                                              Согласен, бывает!
                                                                                Цитата JoeUser @
                                                                                Версию поменяли, осознали свою неправоту.
                                                                                Сейчас я кого-то буду терзать! Итак, установил наисвежайший (скачал с http://downloads.activestate.com/ActivePer...-x64-404865.exe) Перл; запустил, и что же я вижу: на "(-32)**(0.2)" выдаёт "NaN"! Как это понимать, Joe??? Я, конечно, полный ноль в Перле, но всё же ожидал подтверждение ваших слов, а не вижу нисколько!! Жесточайше жду разъяснений! :angry: :blush:

                                                                                П.С. и на "(-32)**(-0.2)" выдаёт это же "NaN"!
                                                                                  Славян, жесточайше а-би-с-ня-ю!!! Установи Perl 6.x
                                                                                    хотя ... операции со "скобками" меня смущают! Без скобок - все норм. Надо смареть синтаксис. Увы, в 6-ю версию я таки и не заехал. Там я нуль.
                                                                                      Цитата Akina @
                                                                                      Честнее написать x^(-3/7) = (x^(N/7))^(-3*N), где N - натуральное. И нечётность корня как-то сразу поплыла...

                                                                                      Тогда уж (x^(1/(7*N))). А дальше вспоминаем о комплексной плоскости, считаем в комплексных числах, потом ограничиваем множество допустимых решений действительными и выясняем, что решение одно для любого N.
                                                                                      Цитата Славян @
                                                                                      даже если в Си написать:

                                                                                      float a=0.2f;
                                                                                      if( a==0.2f )

                                                                                      то будет же истина

                                                                                      Помнится, турбопаскаль мне на такое выдавал ложь, пока тип а не стал extended. Это правда оффтоп слегка.
                                                                                      Цитата Jin X @
                                                                                      Ага, и какова будет скорость работы такой функции? В случае, если Q = 1E15, например...

                                                                                      Зависнет :rolleyes: И тогда контрвопрос, а если число было изначально иррациональным (до перевода в машинное представление), как ловить ошибку?
                                                                                        Цитата JoeUser @
                                                                                        Установи Perl 6.x
                                                                                        Ну поставил какую-то Ракуду: http://rakudo.org/downloads/star/rakudo-st..._64%20(JIT).msi
                                                                                        Цитата
                                                                                        The recommended way to use Rakudo is by downloading Rakudo Star – a useful and usable production distribution of Perl 6. Rakudo Star includes both the Rakudo compiler and some commonly used libraries.
                                                                                        Так на строчку "print (-32)**0.2" она мне наваяла "NaN". Всё, на сегодня лимит испытаний с Перлом завершён, надежды ещё ниже упали, а ещё более глубоких объяснений, Joe, буду ждать!! (опять версия не та и всё такое?.. :whistle: )
                                                                                          https://ideone.com/DXI2ZD - это все относительно Perl 6.
                                                                                          Далее мне неинтересно.
                                                                                            Так и у меня пишет -0.5. Беда же в том, что скобки норм работают и (32)**(-0.2) тоже канает и тоже пишет 0.5. Однако занос минуса в скобки (-32)**(-0.2) всё ломает. Вывод: вы, Joe, прогнали насчёт того, что унарный минус сначала скушается, а потом степень возьмётся. Я в печали. Перл тоже не смог взять и посчитать "правильно" выражение. :'(
                                                                                              Цитата JoeUser @
                                                                                              Я читаю, и у меня из глаз льется кровь! Что такое "отрицательная степень", что такое "дробная степень" все же знают? Все знают как меняется знак от четности/нечетности возведения в степень, все знают что можно извлекать корень нечетной степени из отрицательного числа не уходя в комплексное исчисление? Нафига все эти домыслы?!!! Неужели курса математики старших классов мало???!
                                                                                              В моём понимании проблема в том, что мы не можем с уверенностью заявлять, то -0.2 = -1/5. Как ни прискорбно. Потому что это может быть -0.2000000000000000000000012345 или (наверное) -2/10, как кто-то выше говорил.
                                                                                              Короче говоря, у меня только 1 мысль: встроить callback-функцию, которая будет вызывать юзерскую процедуру, а эта процедура уже будет решать что делать с этим безобразием...
                                                                                              Плюс сделать ещё пару функций типа Root (корень нужной степени) и FracPower (где задаются X, P, Q, т.е. это комбинация Root и Power).
                                                                                                Цитата Jin X @
                                                                                                В моём понимании проблема в том, что мы не можем с уверенностью заявлять, то -0.2 = -1/5. Как ни прискорбно. Потому что это может быть -0.2000000000000000000000012345 или (наверное) -2/10, как кто-то выше говорил.
                                                                                                Короче говоря, у меня только 1 мысль: встроить callback-функцию, которая будет вызывать юзерскую процедуру, а эта процедура уже будет решать что делать с этим безобразием...
                                                                                                Плюс сделать ещё пару функций типа Root (корень нужной степени) и FracPower (где задаются X, P, Q, т.е. это комбинация Root и Power).

                                                                                                Jin X, дружище! Не нужно путать теплое с мягким! Есть математика со своими правилами/законами, и есть исчисление на регистрах, со своими заморочками и ограничениями. Понятие "с этим безобразием" - означает только одно, ты не проработал "правила игры" в должной мере. Как правильно (математика) ты знаешь, как может быть (компьютерное представление и исчисление) - ты тоже знаешь. Задача простая - найти способ максимального соответствия. Предвижу вопрос "это ппц сложно", а кто сказал что должно быть просто?
                                                                                                  Надо просто написать отдельную функцию, которая возводит число не в целую или вещественную степень а в дробную (с явно заданными числителем и знаменателем показателя). Функция должна сократить получающуюся дробь и в зависимость от чётности знаменателя после сокращения выдать результат или сообщить об ошибке.

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

                                                                                                  Можно даже использовать (написать) тип/класс для представления дроби, если так будет удобнее, в этом случае имеет смысл снабдить его всеми необходимыми операциями.
                                                                                                  В языках со статической типизацией это будет или перегруженная функция или функция обозначенная суффиксом (в Си есть функции pow и powi, пусть будет ещё и powfrac, например)
                                                                                                  В языках с динамической типизацией можно проверить тип показателя степени.
                                                                                                    Цитата amk @
                                                                                                    Функция должна сократить получающуюся дробь и в зависимость от чётности знаменателя после сокращения выдать результат или сообщить об ошибке.

                                                                                                    +1
                                                                                                      Эх, amk, есть, конечно, польза и мудрость в ваших словах, но простым людям это слишком излишне, запутано. Пишущий pow(-32,-0.2f) не станет гадать и посылать числитель со знаменателем! А число 0,2 в машине (сколько я прикидываю) действительно не так запишется, а с табуном нулей опосля 2: 0,20000000000***. Т.о., нужно поменять аж компилятор, дабы он понял, что записали -0,2 и постарался выдать те самые честные числитель со знаменателем!! Какая-то жесточайшая специфика=особенность возникает, - никто (думается) на таковое не пойдёт.
                                                                                                        Цитата amk @
                                                                                                        в Си есть функции pow и powi, пусть будет ещё и powfrac, например
                                                                                                        Так, я и говорю, что нужно сделать несколько функций: Power, Root и FracPower (или PowerFrac).

                                                                                                        Прикол просто в том, что обычно числа передаются как вещественные и могут быть результатом какого-то выражения. Этот случай тоже хотелось бы предусмотреть.
                                                                                                        Скажем, мы делаем калькулятор, юзер ввёл функцию (-2)^(3/7). Можно попытаться распознать выражение в скобках как дробь и использовать FracPower(-2, 3, 7), а можно использовать функцию PowerECB, которой мы будем передавать callback-функцию, разбивающую вещественное число на P и Q (по возможности). Единственное, что мне тут не нравится – это элемент случайности, т.е. если строить график функции (-2)^SIN(X), то функцию возможно будет вычислять "через раз" (или даже реже), т.к. во многих случаях результат типа 0.7642232323567763 вряд ли удастся представить с нечётным Q. И исходя из этого вся эта затея кажется абсурдной.

                                                                                                        Вообще, как я понимаю, во FracPower при X < 0 параметр Q должны быть целым и больше 0, так ведь (ведь не существует корней дробной, нулевой или отрицательной степени)? А вот P может быть любым. И при X > 0 значение Q может быть любым. Верно? :)
                                                                                                          Цитата Jin X @
                                                                                                          при X > 0 значение Q может быть любым. Верно?

                                                                                                          Ненулевым ;)

                                                                                                          Цитата Jin X @
                                                                                                          Вообще, как я понимаю, во FracPower при X < 0 параметр Q должны быть целым и больше 0, так ведь (ведь не существует корней дробной, нулевой или отрицательной степени)? А вот P может быть любым.

                                                                                                          Я так понял, что функция FracPower должна иметь сигнатуру (double,int,int). Тогда если X<0, то Q должно быть положительным и нечетным, либо при делении на НОД(P,Q) становиться нечетным.
                                                                                                          Цитата Jin X @
                                                                                                          функции (-2)^SIN(X)

                                                                                                          А она вообще определена на непрерывном множестве? Что-то мне подсказывает, что нет. :) Даже на комплексной плоскости.
                                                                                                            Это у вас плохое предсказание. В комплексных числах она вполне нормально определена и ведёт себя (чрез экспоненту и логарифм распишите и увидите).
                                                                                                            Вообще суть проблемы в том, что действительно операция (-2)y для вещественного результата - неустойчивая, т.е. малые изменения вполне способны бросать значения из действительного результата в комплексные.
                                                                                                            Так что самым надёжным итогом будет написание функции:
                                                                                                            Степень( число x, строка y) = xy,
                                                                                                            чтобы анализировать запись 'y' и пытаться понять: искать ли вещ.корни, или их не бывает.
                                                                                                              Цитата Славян @
                                                                                                              А число 0,2 в машине (сколько я прикидываю) действительно не так запишется, а с табуном нулей опосля 2: 0,20000000000***. Т.о., нужно поменять аж компилятор, дабы он понял, что записали -0,2 и постарался выдать те самые честные числитель со знаменателем!!

                                                                                                              Что то я не понимаю, а почему не округлить нужное число до второго знака, тем самым получив нужное число, без табуна нулей опосля 2?
                                                                                                                Аппаратно нельзя. Особенность маш. представления чисел в x86.
                                                                                                                  Цитата KILLER @
                                                                                                                  почему не округлить нужное число до второго знака, тем самым получив нужное число, без табуна нулей опосля 2?

                                                                                                                  Потому, что там не только нули. Отрицательное число можно возводить в дробную степень, где целый числитель и целый нечётный знаменатель, типа 1/3, 2/7. Ни одно из таких чисел нельзя представить конечной двоичной дробью, но float или double представлены именно конечной двоичной дробью.
                                                                                                                    Цитата KILLER @
                                                                                                                    Что то я не понимаю, а почему не округлить нужное число до второго знака, тем самым получив нужное число, без табуна нулей опосля 2?
                                                                                                                    Так это и есть округлённое до второго (десятичного) знака число. Но не забывай, в компьютерах используется двоичное представление чисел, поэтому десятичные дроби не представимы точно. Почему, Mikle уже написал.
                                                                                                                    Цитата Славян @
                                                                                                                    Аппаратно нельзя. Особенность маш. представления чисел в x86.
                                                                                                                    Не только в x86. Этим страдают все аппаратные представления вещественных чисел.
                                                                                                                      Цитата amk @
                                                                                                                      Не только в x86. Этим страдают все аппаратные представления вещественных чисел.
                                                                                                                      Я убеждён, что в какой-нибудь машине сделали/делали не только расчёт в двоичной системе, но и в иных, и даже в десятеричной.
                                                                                                                        Сетунь считала в троичной. Калькуляторы считают преимущественно в десятичной.
                                                                                                                        Также в десятичной системе считали некоторые машины в 60-х, 70-х годах. Точнее в двоично-десятичной.
                                                                                                                        Сейчас недвоичных машин практически не осталось. Да и те выполняют роль скорее музейных экспонатов.
                                                                                                                          Погодите, а на чём Ява то считает? Их же тупой интерпретатор вполне способен скушать десятичное представление числа в записи строки pow(-32,-0.2) (или как у них там?) и выдать норм ответ!? Или просто решили забить?
                                                                                                                            Цитата Славян @
                                                                                                                            Их же тупой интерпретатор вполне способен скушать десятичное представление числа в записи строки 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,1322 ]   [ 16 queries used ]   [ Generated: 19.04.24, 04:49 GMT ]