2015-03-08 6 views
2

Если вы поручите J рассчитать большой результат по имени точности по умолчанию, вы быстро столкнетесь с случаями, когда он говорит, что результат равен бесконечности _. Это из-за того, что бесконечность означает математически.Как заставить J дать ошибку вместо неправильного возврата бесконечности?

Как я могу дать указание J дать ошибки вместо бесконечности при превышении стандартной точности? Могу ли я установить это значение по умолчанию в моей установке J?

например.

!1000x NB. Extended precision gives large finite result. 
4023872600770937735437024339230039857193748642107146325437999104299385123986290205920442084869694048004799886101971960586316668729948085589013238296699445909974245040870737599188236277271887325197795059509952761208749754624970436014182780946464962910563938... 

    !1000 NB. Default precision claims infinity. I'd generally prefer an error. 
_ 
+1

Вы можете использовать [assert] (http://www.jsoftware.com/help/learning/29.htm), но почему вы хотите это сделать? – Eelvex

+0

@eelvex Практически говоря, если я создаю и проверю слово, я не хочу использовать его в более сложном выражении и выясню, что несколько большее входное значение вызвало распространение неправильных результатов '_' через весь расчет , Философски говоря, я хочу, чтобы мои программы давали правильные результаты или отказывались работать. – dukereg

+0

Я бы сказал, что 'assert' - это путь. – Eelvex

ответ

3

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

SafeFactorial =: 3 : 0 
p =. ! y 
assert. p < _ 
assert. p > __ 
p 
) 
    SafeFactorial 5 
120 
    SafeFactorial 50 
3.04141e64 
    SafeFactorial 500 
|assertion failure: SafeFactorial 
| p<_ 

Важное предостережение от комментариев:

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

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

+4

Я уже добавил этот комментарий к другому ответу, но стоит упомянуть здесь об этом более высокоприоритетном: это, безусловно, способ добиться эффекта, которого требует OP, но я не уверен, что это действительно * желательно * из оперативного перспектива. J - это ориентированный на массив язык, и это редкое обстоятельство, когда один работает только на одном номере. Как правило, вход в функции, такие как факториал, - это массивы с несколькими номерами *, поэтому, если вы создаете функцию для генерирования такой ошибки, это исключает возможность получения каких-либо результатов вообще *, даже правильные результаты *, если ** один * * атом плохой. –

0

Это не может делать то, что вы хотите, потому что он использует формат иностранных конъюнкции 8!:0 изменить бесконечность на то, что вы хотели бы (в том числе и «ошибки»). Конечно, это похоже на ошибку; то, что он действительно делает, заменяет '_' на 'error', так что это может быть не то, что вы хотите. Результатом также являются строки в коробке, которые могут не соответствовать вашим ограничениям.

inf=: 'd<error>'&(8!:0) 
    % i.6 
_ 1 0.5 0.333333 0.25 0.2 
    inf % i.6 
┌─────┬───────────┬───────────┬───────────┬───────────┬───────────┐ 
│error│1.000000000│0.500000000│0.333333333│0.250000000│0.200000000│ 
└─────┴───────────┴───────────┴───────────┴───────────┴───────────┘ 

Дополнительную информацию можно найти в 8 !: записи для иностранных союзов в словаре J. http://www.jsoftware.com/help/dictionary/dx008.htm

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

9!:35 [ 1 NB. to set the assert. flag on 
    test =: 3 : 0 
​assert. _~:%y NB. to see if _ shows up in the result of %y 
​%y 
​) 
    test 1 + i.5 
1 0.5 0.333333 0.25 0.2 
    test i.5 
|assertion failure: test 
| _~:%y 
+0

Чтобы уточнить, мое намерение состоит в возникновении фактической ошибки; отказ продолжать, когда он не может вычислить правильные результаты. Форматирование бесконечности как '_' меня не беспокоит. – dukereg

+3

@dukereg Проблема с ошибкой в ​​'_' заключается в том, что это приведет к сбою * всей операции *, то есть если вы'! 'В массиве 10x10, вы не получите никаких * результатов *, даже если бы одно число во всем массиве выходит за пределы диапазона. Фактически, это самое наблюдение отвечает за общую философию в J передачи информации через результаты внеполосного возвращения (например, бесконечность), а не для того, чтобы бросать ошибки. –

4

Моя цель состояла в том, чтобы получить математически правильные результаты. Я подскочил к выводу, что я должен потерпеть неудачу рано, вместо того, чтобы давать неверные результаты, как в Java. То, что я точно попросил, было покрыто датчанами и Eelvex, и они заслуживают всякой благодарности за это.

Некоторые наблюдения, хотя, которые могут помочь другим получить в мышлении J:

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

Во-вторых, я уже наблюдал глаголы, например, например.dyadic i., которые возвращают негабаритные результаты вместо отказа. Это распространено в J, и я должен научиться фильтровать результаты, которые я не хочу, вместо того, чтобы мои программы постоянно отображали ошибки.