DIM giving number too big
-
- Posts: 37
- Joined: Thu 05 Apr 2018, 14:08
DIM giving number too big
I must be having a brain fart, I can't see what's going wrong (out of tea error?).
I've just installed BBC BASIC for SDL 1.40a on a new tablet (Galaxy Tab, Android 13), and running some existing code fails. I've isolated it to:
DIM mem% 65535
Number too big
Doing some checks reveals the heap is high up in memory compared to my other tablet and on Windows:
>PRINT ~HIMEM
EDB08C00
>PRINT ~LOMEM
EBB08D4A
>PRINT HIMEM-LOMEM
33554102
>*HEX64
>PRINT ~LOMEM
EBB08D4A
>mem%=LOMEM
Number too big
>mem%%=LOMEM
>PRINT ~mem%%
EBB08D4A
Is the DIM thinking it's trying to allocate memory at a negative location or something? It's not running into 64-bit addresses requiring %% variables.
I've just installed BBC BASIC for SDL 1.40a on a new tablet (Galaxy Tab, Android 13), and running some existing code fails. I've isolated it to:
DIM mem% 65535
Number too big
Doing some checks reveals the heap is high up in memory compared to my other tablet and on Windows:
>PRINT ~HIMEM
EDB08C00
>PRINT ~LOMEM
EBB08D4A
>PRINT HIMEM-LOMEM
33554102
>*HEX64
>PRINT ~LOMEM
EBB08D4A
>mem%=LOMEM
Number too big
>mem%%=LOMEM
>PRINT ~mem%%
EBB08D4A
Is the DIM thinking it's trying to allocate memory at a negative location or something? It's not running into 64-bit addresses requiring %% variables.
-
- Posts: 272
- Joined: Tue 18 Jun 2024, 09:32
Re: DIM giving number too big
DIM (used this way) allocates memory from the heap, the value it returns in the specified variable is a pointer (or address, if you prefer). Hence the variable must be of a type which can hold an arbitrary pointer, which in practice means either a suffixless variable or a 64-bit integer variable:
Code: Select all
DIM mem 65535
DIM mem%% 65535
Code: Select all
*HEX 64
DIM mem%% 65535
PRINT ~mem%%
If you are writing portable code, using the suffixless variable mem might be preferable, because whilst not all versions of BBC BASIC support 64-bit integers they all* should be able to store a pointer in such a variable.
* Matrix Brandy cannot hold an arbitrary 64-bit integer in a suffixless variable, but I think it should be able to hold any valid x86-64 pointer.
-
- Posts: 37
- Joined: Thu 05 Apr 2018, 14:08
Re: DIM giving number too big
>DIM MEM 65535:PRINT ~MEM
EBB08D5B
>DIM MEM%% 65535:PRINT ~MEM%%
EBB18D6C
>DIM MEM% 65535:PRINT ~MEM%
Number too big
(quit and restart)
*HEX64
>DIM MEM 65535:PRINT ~MEM
EBB08D5B
>DIM MEM%% 65535:PRINT ~MEM%%
EBB18D6C
>DIM MEM% 65535:PRINT ~MEM%
Number too big
(quit and restart)
*HEX32
>DIM MEM 65535:PRINT ~MEM
EBB08D5B
>DIM MEM%% 65535:PRINT ~MEM%%
EBB18D6C
>DIM MEM% 65535:PRINT ~MEM%
Number too big
Nothing is more than 32 bits, but are more than 31 bits. On my LG4 Android smartphone the values are 431D56, etc.
Changing all references of mem% to mem would be a huge job, as it would also require changing loads of other variables that reference mem%, such as err%=mem%+&FF00:base%=mem%+&100 ... load%=mem%!(r%(2)) ... src%=mem%?r%(7) etc, and rewriting loads of libraries $(mem%+X%)=FNdis(mem%?(X%+2),mem%!(X%+4)) etc.
EBB08D5B
>DIM MEM%% 65535:PRINT ~MEM%%
EBB18D6C
>DIM MEM% 65535:PRINT ~MEM%
Number too big
(quit and restart)
*HEX64
>DIM MEM 65535:PRINT ~MEM
EBB08D5B
>DIM MEM%% 65535:PRINT ~MEM%%
EBB18D6C
>DIM MEM% 65535:PRINT ~MEM%
Number too big
(quit and restart)
*HEX32
>DIM MEM 65535:PRINT ~MEM
EBB08D5B
>DIM MEM%% 65535:PRINT ~MEM%%
EBB18D6C
>DIM MEM% 65535:PRINT ~MEM%
Number too big
Nothing is more than 32 bits, but are more than 31 bits. On my LG4 Android smartphone the values are 431D56, etc.
Changing all references of mem% to mem would be a huge job, as it would also require changing loads of other variables that reference mem%, such as err%=mem%+&FF00:base%=mem%+&100 ... load%=mem%!(r%(2)) ... src%=mem%?r%(7) etc, and rewriting loads of libraries $(mem%+X%)=FNdis(mem%?(X%+2),mem%!(X%+4)) etc.
-
- Posts: 272
- Joined: Tue 18 Jun 2024, 09:32
Re: DIM giving number too big
Yes it is, with the qualifier that it must be a valid signed 32-bit number:
Code: Select all
*HEX64
>DIM MEM 65535:PRINT ~MEM
EBB08D5B
Only when considered to be an unsigned 32-bit number is it in range, but BBC BASIC has no unsigned 32-bit data type!
Within a single program (i.e. source code unit) it's a trivial global search-and-replace operation, which any half-decent IDE can do in a couple of seconds.Changing all references of mem% to mem would be a huge job
Admittedly if you have many files which need changing then it could indeed be a big job, in which case your option is not to change it and accept that your program isn't compatible with 64-bit platforms. There's no 'magic' that can make a 64-bit platform allocate memory only in the range that can be represented by a signed 32-bit address.
We should be grateful that Acorn was so forward-looking that they supported 32-bit integers from the start, even though there were probably no computers that needed a 32-bit address then. I think we can forgive them for not anticipating the need for 64-bit addresses in 1981!
-
- Posts: 272
- Joined: Tue 18 Jun 2024, 09:32
Re: DIM giving number too big
Traditionally (by which I mean the original Kemeny & Kurtz BASIC of 1964) numeric variables were not typed at all, there was just one numeric data type represented by a suffixless variable name, capable of holding either a floating-point number or an integer. My view has always been that this is how BASIC should have remained, and there are indeed some 'modern' BASICs which still adhere to this tradition, for example Liberty BASIC.Richard Russell wrote: ↑Sat 02 Nov 2024, 16:45 Only when considered to be an unsigned 32-bit number is it in range, but BBC BASIC has no unsigned 32-bit data type!
I know that the potential value of having multiple numeric data types is that it can reduce the storage requirements, especially of arrays. For example in BB4W and BBCSDL the array number(999) occupies 10000 bytes whereas the array number%(999) occupies only 4000 bytes, a worthwhile saving which becomes even more important with larger arrays.
So Acorn can be forgiven for including an integer data type in BBC BASIC, but life would have been easier in some respects if they hadn't. If there had been just one numeric type the problem of a 32-bit integer variable no longer being able to contain a pointer wouldn't have occurred, and there would have been no need to introduce 64-bit integers.
But we are where we are. At least, fortunately, we are in the position that every version of BBC BASIC (I think) can hold an arbitrary pointer in a suffixless numeric variable. This might not have been the case, had for example Acorn chosen to use a 32-bit floating-point format rather than 40-bits. Or had the x86-64 architecture not been limited to a 48-bit signed memory address.
-
- Posts: 37
- Joined: Thu 05 Apr 2018, 14:08
Re: DIM giving number too big
I thought it might be that, but I'm used to integers being able to reference 32-bit quantities regardless of what they are.Richard Russell wrote: ↑Sat 02 Nov 2024, 16:45Yes it is, with the qualifier that it must be a valid signed 32-bit number:
A work-around which looks workable is something like:
IF thing THEN
DIM mem%% memsz%:IF !(4+^mem%%) THEN PROCexit("Can't access 64-bit memory")
mem%=0:!^mem%=!^mem%%
ELSE
DIM mem% memsz%
ENDIF
Being able to reference more than just 64K needs 32-bit integers, and file sizes, even in 1981, are very easy to get past 64K.Richard Russell wrote: ↑Sat 02 Nov 2024, 16:45We should be grateful that Acorn was so forward-looking that they supported 32-bit integers from the start, even though there were probably no computers that needed a 32-bit address then.
-
- Posts: 272
- Joined: Tue 18 Jun 2024, 09:32
Re: DIM giving number too big
Not in any version of BBC BASIC I know. Even in Sophie's original 6502 BASIC this results in an error (2^32 - 1 is the valid unsigned 32-bit number &00000000FFFFFFFF):
Code: Select all
> A = 2^32 - 1
> A% = A
Too big
I'm not sure what that is trying to achieve, but it will call PROCexit even in the case of a perfectly valid address at the top of memory which can be represented as a signed-32-bit number (I think all 64-bit processor architectures can allocate memory both at the bottom and the top of the valid pointer address range).A work-around which looks workable is something like:
DIM mem%% memsz%:IF !(4+^mem%%) THEN PROCexit("Can't access 64-bit memory")
Acorn could have used 16-bit integer variables, many contemporary BASICs did. That wouldn't have limited file sizes or any other uses of larger numeric values since regular 'floating point' variables can contain any arbitrary integer value from -2^32 to +2^32 without loss, which encompasses all signed and unsigned 32-bit values.Being able to reference more than just 64K needs 32-bit integers, and file sizes, even in 1981, are very easy to get past 64K.
-
- Posts: 37
- Joined: Thu 05 Apr 2018, 14:08
Re: DIM giving number too big
Hmmm... This is going to need another pot of tea...
DIM mem%% memsz%:mem%=0:!^mem%=!^mem%% (edited for conciseness)
...
esc%=&FF00:err%=&FF01
...
mem%?esc%=0
BANG!
That should be accessing location
00000000EBB08D5B
000000000000FF00 +
-----------------------
00000000EBB17D5B
but I bet it's ending up accessing a "negative" address.
FFFFFFFFEBB08D5B sign extended
000000000000FF00 +
-----------------------
FFFFFFFFEBB17D5B
DIM mem%% memsz%:mem%=0:!^mem%=!^mem%% (edited for conciseness)
...
esc%=&FF00:err%=&FF01
...
mem%?esc%=0
BANG!
That should be accessing location
00000000EBB08D5B
000000000000FF00 +
-----------------------
00000000EBB17D5B
but I bet it's ending up accessing a "negative" address.
FFFFFFFFEBB08D5B sign extended
000000000000FF00 +
-----------------------
FFFFFFFFEBB17D5B
-
- Posts: 37
- Joined: Thu 05 Apr 2018, 14:08
Re: DIM giving number too big
An initial thought for a test for mem%% being outside the range &0000000000000000-&00000000FFFFFFFF by testing bit32-bit63 of mem%%.Richard Russell wrote: ↑Sat 02 Nov 2024, 18:34I'm not sure what that is trying to achieve, but it will call PROCexit even in the case of a perfectly valid address at the top of memory which can be represented as a signed-32-bit number (I think all 64-bit processor architectures can allocate memory both at the bottom and the top of the valid pointer address range).
Last edited by jgharston on Sat 02 Nov 2024, 18:59, edited 1 time in total.
-
- Posts: 272
- Joined: Tue 18 Jun 2024, 09:32
Re: DIM giving number too big
No, it "should be" (and is) accessing the location:
Code: Select all
FFFFFFFFEBB08D5B
000000000000FF00 +
----------------
FFFFFFFFEBB17D5B