pidd wrote: ↑Tue Sep 28, 2021 5:46 am

For 64 bit multiply you might have to split into four 32 bit numbers, do three multiplications, shift left32 two of the numbers then add the other.

Unfortunately BBC basic error trapping doesn't let you resume on error which in some languages ignores the overflow.

It seems I need to split the numbers into six 24-bit numbers as multiplication of 0xFFFFFFFF by 0xFFFFFFFF, for example, results in a 64-bit number which is too big.

The code

Code: Select all

```
1000 *hex64
1020 FOR i%%=1 TO 20
1030 PRINT STR$~(FNipoly8%%(i%%))
1040 NEXT i%%
1999 END
2000 DEF FNmul64%%(a%%,b%%)
2010 LOCAL al%%,am%%,ah%%
2020 LOCAL bl%%,bm%%,bh%%
2030 LOCAL zl%%,zm%%,zh%%
2040 al%%=a%% AND &FFFFFF
2050 am%%=(a%%>>24) AND &FFFFFF
2060 ah%%=a%%>>48
2070 bl%%=b%% AND &FFFFFF
2080 bm%%=(b%%>>24) AND &FFFFFF
2090 bh%%=b%%>>48
2100 zl%%=al%%*bl%%
2110 zm%%=al%%*bm%%+am%%*bl%%
2120 zh%%=(al%%*bh%%+am%%*bm%%+ah%%*bl%%) AND &FFFF
2130 =FNadd64%%(FNadd64%%(zh%%<<48,zm%%<<24),zl%%)
2200 DEF FNadd64%%(c%%,d%%)
2210 LOCAL cl%%,ch%%
2220 LOCAL dl%%,dh%%
2230 LOCAL yl%%,yh%%,yc%%
2240 cl%%=c%% AND &FFFFFFFF
2250 ch%%=c%%>>32
2260 dl%%=d%% AND &FFFFFFFF
2270 dh%%=d%%>>32
2280 yl%%=cl%%+dl%%
2290 yc%%=yl%%>>32
2300 yh%%=(ch%%+dh%%+yc%%) AND &FFFFFFFF
2310 =yh%%<<32 OR (yl%% AND &FFFFFFFF)
2400 DEF FNipoly8%%(x%%)
2410 LOCAL x2%%,r%%
2420 x2%%=FNmul64%%(x%%,x%%)
2430 r%%=FNadd64%%(FNmul64%%(x2%%,x2%%),&4cca10b00bc5da27)
2440 r%%=FNadd64%%(FNmul64%%(r%%,x2%%),&872a4954ca3a3537)
2450 r%%=FNadd64%%(FNmul64%%(r%%,x%%),&2bf0e3ddcc4fb44f)
2460 r%%=FNadd64%%(FNmul64%%(r%%,x%%),&b5ad4eceda1ce2a9)
2470 =r%%
```

produces the output

Code: Select all

```
>RUN
B5928CB17C6CA657
F6D946DE5802C393
45EBD61714B1FE7D
A226239E74DA2E55
3DD5A938556A29AB
7E397129ADE49EAF
FB8216389069FEE1
80D1C3AC29CA42E1
C3C354CC1A1E89F
CEC6B763BA862BAB
2C6826BB924514E5
BC08F09FE23E9C4D
478312DD5FDCB533
CBA21BC1DD30BA87
78232A1C49BD4E89
AFB4ED3CB3745E99
7F7A4F447F19967
497D219555FA4343
6FC8C3F34F4BF1CD
A94F7D62CAC455C5
```

Julia confirms this is correct.

Code: Select all

```
julia> function ipoly8(p)
x=UInt64(p)
x2=x*x
return (((x2*x2+
0x4cca10b00bc5da27)*x2+
0x872a4954ca3a3537)*x+
0x2bf0e3ddcc4fb44f)*x+
0xb5ad4eceda1ce2a9
end
ipoly8 (generic function with 1 method)
julia> using Printf
julia> for i=1:20
@printf("%x\n",ipoly8(i))
end
b5928cb17c6ca657
f6d946de5802c393
45ebd61714b1fe7d
a226239e74da2e55
3dd5a938556a29ab
7e397129ade49eaf
fb8216389069fee1
80d1c3ac29ca42e1
c3c354cc1a1e89f
cec6b763ba862bab
2c6826bb924514e5
bc08f09fe23e9c4d
478312dd5fdcb533
cba21bc1dd30ba87
78232a1c49bd4e89
afb4ed3cb3745e99
7f7a4f447f19967
497d219555fa4343
6fc8c3f34f4bf1cd
a94f7d62cac455c5
```

I did some of my debugging using the Linux Console version of BBC Basic and obtained a segment fault from something like

at one point. Note the exclamation point was meant to be a tilde.

While I was able to reproduce the typo, I was unfortunately not able to reproduce the crash. No errors occurred with the Pico.