понимание чисел в рубиновых рациональных числах - PullRequest
4 голосов
/ 07 мая 2011

из http://www.ruby -doc.org / core / classes / Rational.html

Rational(10) / 3   #=> (10/3)
Rational(10) / 3.0 #=> 3.3333333333333335

Rational(-8) ** Rational(1, 3)
                  #=> (1.0000000000000002+1.7320508075688772i)

Я понимаю первые два, но не последний. Обратите внимание, что Rational(8) ** Rational(1, 3) работает просто отлично, и нет контекста с плавающей запятой, чтобы запутать воду. Может кто-нибудь объяснить мне, и как получить -2, как я должен получить?

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

edit # 2 (благодаря pst и Mat) : согласно примеру с pst:

>> (Rational(-8) ** Rational(1,3)) ** Rational(3)
=> (-8.0+3.1086244689504383e-15i)

Это отличный пример того, почему я хочу вернуть Реальный ответ, когда это возможно (я был бы гораздо более снисходительным, если бы это был класс Complex, разбрасывающий комплексные числа, но это класс Rational - I ' Я позволю себе сказать, что он должен вести себя (). Ответ Мата иллюстрирует, почему кто-то может захотеть общего решения, такого как обезьяна-исправление для Rationals (или сложного класса и т. Д.) Или класса-оболочки: потому что в противном случае я не могу лениво писать свой код, обрабатывая основные математические операции с относительной точностью. *

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

Ответы [ 3 ]

3 голосов
/ 07 мая 2011

Ответ не -2: ответ 2i. К сожалению, математика не удалась. В любом случае, частей остальных по-прежнему актуальны в некотором роде. См. Комментарий Мата и ответ Саввы.

Это не объясняет, почему в выводе нет просто 2i (или (0+2i)), я подозреваю, что это просто из-за внутренних ошибок округления (он не пытается заменить matlab). См. ответ Савы о том, как "понять" результат возвращенного комплексного числа.

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

Рассмотрим:

>> (Rational(-8) ** Rational(1,3)) ** Rational(3)                       
=> (-8.0+3.1086244689504383e-15i)

Это не за горами!

Однако

>> (Rational(8) ** Rational(1,3)) ** Rational(3)                        
=> 8.0

"идеально". Надеюсь, кто-то может запустить с этим.

Удачного кодирования.


Отредактируйте, хорошо, вот что происходит: Результат Rational ** Rational равен , а не a Rational.

Когда реальный результат Rational ** Rational -> Float, но когда результат содержит мнимый компонент, тогда Rational ** Ration -> Complex.

В «идеальном» случае мы просто оставались в пределах точности Float (по крайней мере, достаточно, чтобы получить «красивый результат»). В случае, когда в результате получается сложный объект, из-за того, что он был сохранен в вещественной + мнимой части, а затем была выполнена математическая обработка данных позже, границы относительной точности Float объединенных компонентов не были достаточно хорошими.

2 голосов
/ 07 мая 2011

(1.0000000000000002+1.7320508075688772i), вероятно, представляет 1+\sqrt{3}i, и это один из правильных ответов:

(1+\sqrt{3}i)^3 = -8

Что с ним не так?

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

-Rational(8) ** Rational(1, 3)
# => -2.0

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

2 голосов
/ 07 мая 2011

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

(-8) ** (1/3) = -(8 ** 1/3)

У меня была похожая проблема на другом языке (см. здесь ), и один из участников дал довольно хорошее объяснение, почему это так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...