Roger's approach also fails if the numbers are big enough. Here's the
original problem, but with the last number changed to protect the innocent
(and make the demonstration work)

   (4 : '13|x*y') / 19 29 59 79 89 109 119 139 149 179 198

3


​Now let's use  some big numbers:​
​
(4 : '13|x*y') / 19 29 59 79 89 109 119 139 149 179 198 + 10^20
0​

But if we use extended precision:

     (4 : '13|x*y') / 19 29 59 79 89 109 119 139 149 179 198 + 10x^20

1


Showing interim results:

     (4 : '13|x*y') /\. 19 29 59 79 89 109 119 139 149 179 198 + 10x^20

1 7 6 2 8 3 3 5 1 7 100000000000000000198


For that matter, my original approach will work with the same big numbers
as long as you use extended precision:

   13|*/13|/ 19 29 59 79 89 109 119 139 149 179 198 + 10x^20

1


However, 0 can be a valid result in these remainder problems.  Notice the
changed last digit (195 is a multiple of 13):

     (4 : '13|x*y') / 19 29 59 79 89 109 119 139 149 179 195

0


    (4 : '13|x*y') /\. 19 29 59 79 89 109 119 139 149 179 195

0 0 0 0 0 0 0 0 0 0 195


Any number in the list which is a multiple of 13, will cause the final
answer to be zero.


So you can't rely on a zero answer to indicate a "precision exceeded"
error. Which is why it would be nice to have a way to be notified when you
are exceeding the precision limit.


Skip


Skip Cave
Cave Consulting LLC

On Mon, Sep 18, 2017 at 3:48 PM, Skip Cave <s...@caveconsulting.com> wrote:

> So does Roger's function work on the larger list? Let's see:
>
>     (4 : '13|x*y') / 10 # 19 29 59 79 89 109 119 139 149 179 199
>
> 9
>
> That looks like it does. Let's check with extended precision:
>
>     (4 : '13|x*y') / 10 # 19 29 59 79 89 109 119 139 149 179 199x
>
> 9
>
> So Roger's approach works without extended precision. But mine doesn't:
>
>
>    13| */13|/ 10 # 19 29 59 79 89 109 119 139 149 179 199
>
> 0
>
> Let's see why. Here's Roger's verb. We'll call it 'g':
>
>    g=. 4 : '13|x*y'
>
> Roger does g/ which puts g between each integer. Let's see what is going
> on In the short case:
>
>      19 g 29 g 59 g 79 g 89 g 109 g 119 g 139 g 149 g 179 g 199
>
> 4
>
>
> Step-by-step...
>
>
>     179 g 199
>
> 1
>
>     149 g 1
>
> 6
>
>     139 g 6
>
> 2
>
>     119 g 2
>
> 4
>
>     109 g 4
>
> 7
>
>      89 g 7
>
> 12
>
>      79 g 12
>
> 12
>
>      59 g 12
>
> 6
>
>      29 g 6
>
> 5
>
>     19 g 5
>
> 4
>
> So the secret is that Roger's scheme keeps the interim calculation values
> small enough to avoid precision errors. (There's got to be an easier way to
> list the interim values of insert). My scheme generated large interim
> values which exceeded the precision limit.
>
> Skip
>
>
> I get a set of numbers from a database. The
>
> Skip Cave
> Cave Consulting LLC
>
> On Mon, Sep 18, 2017 at 2:51 PM, Skip Cave <s...@caveconsulting.com>
> wrote:
>
>> Roger said:
>>
>>  But if the list were longer:
>>    13 | */ 13 | 10 # 19 29 59 79 89 109 119 139 149 179 199
>> 0
>>
>> Wow! Yes I see the problem. It would be really nice if J would output a
>> warning when a  calculation exceeds the precision limits. I'm sure this
>> would probably  slow down all computations, so having a global variable to
>> turn on precision errors would be a conservative approach.
>>
>> Of course, I can usually check to see if an error has occurred by turning
>> on extended precision to see if the answers match, but it would be nice to
>> know without having to always double check my calculations..
>>
>>    13|*/13|/ 10 # 19 29 59 79 89 109 119 139 149 179 199x
>>
>> 9
>>
>>
>> Skip Cave
>> Cave Consulting LLC
>>
>> On Mon, Sep 18, 2017 at 1:46 PM, Roger Hui <rogerhui.can...@gmail.com>
>> wrote:
>>
>>> Your solution works only because the list isn't too long, and the initial
>>> 13| (same as 13 |/) made them all small enough that you can do the */
>>> without losing precision.  But if the list were longer:
>>>
>>>    13 | */ 13 | 10 # 19 29 59 79 89 109 119 139 149 179 199
>>> 0
>>>
>>> If it makes it more understandable, use explicit defn:
>>>
>>>    (4 : '13|x*y') / 19 29 59 79 89 109 119 139 149 179 199
>>> 4
>>>
>>> "Multiplication mod m" means m|x*y, multiply, then take the remainder of
>>> division by m.
>>>
>>>
>>>
>>>
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to