I'm probably missing the point,  but it's perhaps worth observing that
you might choose to consider ALL the numbers here (except the exponent)
as belonging to the finite field of numbers mod 13,  in which case
"Roger's approach" doesn't fail.

What about 10^20 ?
13&|@(10&^) 20
9

(in fact,
   13&|@(10&^) 8 20 32 44  NB. same for all exponents mod 12 (!)

9 9 9 9   )


   13|10^20x      NB. cf extended

9


(13&|@*/) 19 29 59 79 89 109 119 139 149 179 198  NB. original exercise?
19

   (13&|@*/) 19 29 59 79 89 109 119 139 149 179 198 * 13&|@(10&^) 20
9

Note also:
(13&|@*/) (13 | 19 29 59 79 89 109 119 139 149 179 198) * 13&|@(10&^) 20
9

IF the exponent is itself large-ish,  eg 10^300,  we can use Euler's theorem, qv. which, in this case, leads to 10^400 mod 13 being equivalent to 10^12|400,  mod 13.

Easier of course to just exploit extended integers, provided memory problems don't
preclude them.

Mike


PS - sorry if the layout breaks down - looks ok on sending!


On 19/09/2017 07:14, Skip Cave wrote:
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



---
This email has been checked for viruses by Avast antivirus software.
https://www.avast.com/antivirus
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to