Hypothetically, you could rig up a 9!:n mechanism (to turn this on /
off) and rig up the code that promotes ints to floats print a warning.
You'd probably also want some kind of anti-spam measure in there
(display the warning only once until the user issues another command
line, or something iike that). Then all you need to do is test to make
sure you haven't broken anything and deal with deploying these
changes.

But there's another way, and it's available right now:

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

If your result is floating and you meant for it to be integer, switch
to extended and see if it changes.

That said, if you're working with large numbers (if your numbers can
ever be more than 15 digits), and this kind of precision matters for
you, you should always be working with extended precision values.

Thanks,

-- 
Raul


On Tue, Sep 19, 2017 at 2:14 AM, Skip Cave <s...@caveconsulting.com> 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
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm

Reply via email to