Alyce
Jan 23, 2012
- "Edited for page formatting and grammar."
Numbers in LB/JB Liberty BASIC
(all you ever wanted to know about numbers but did not know whom to ask ;) ) by -
Table of Contents
Numbers could be integers (AKA whole numbers) – without decimal point – and real numbers (AKA floating point numbers).
Integer numbers
Combining integers with + - * MOD operators
Liberty BASIC has no
Long integers (aka Arbitrary length integers)
Now, there is a somewhat unique strong point inQBasic's integer type is stored in 2 bytes, and hence limited to +/- 2^15, from -32,768 to 32,767.
In contemporary
To get all 158 digits of 100! (factorial of 100, defined as 1*2*3*...*99*100) in these languages one has to invent
f=1
n=100
for i=1 to n
f=f*i
next
print len(str$(f))
print f
output is (line breaks added to the long number for page formatting):
158 – number of digits
and factorial itself, hold your breath:
933262154439441526816992388562667004907159682643816214685929638952175999932299156089414639761565182862536979208272237582511852109168640000000000000000000000009332621544394415268169923885626670049071596826438162146859296389
5217599993229915608941463976156518286253697920827223758251185210
916864000000000000000000000000
It looks like the length of those integers is limited only by available memory and computer speed (of course working with these beasts will be slower!). So getting 10^10000 might take several seconds. But it works, and with all digits!
Functions VAL( ) and STR$( ) in
(Of course) +, -, *, as well as ^ and MOD supports long integers.
There are some beneficial
- If a is a long integer, and a/b is supposed to be real number,
- then result will be a long integer (with all digits preserved). Also we evade real overflow.
It looks like
It looks like
Real numbers
Storing (small) integersRange limitation
Here is data on limitation for double-precision numbers from QBasic Help:- Positive 1.79769313486231D+308 4.940656458412465D-324
- Negative -4.940656458412465D-324 -1.79769313486231D+308
Precision limitation
Double real value stores only about 16mask$="#."prints
for i=1 to 20: mask$=mask$+"#": next '20 digits after "."
print using(mask$, 1/3)
print "*.12345678901234567890"
0.33333333333333331968, that is, we get “garbage” after 16-th
*.12345678901234567890
Just checking how small number d should be so 1+d will register as d:
d=1
for i=1 to 20
d=d/10
a=1+d
print i,1-a
next
Precision limitation consequences
This gives some really bad things you should be aware of (and it is not a bug, it is a way real numbers work in pretty much any language):- You should not count on real numbers being exact.
- You should never test real numbers for being exactly equal.
a = 2.1 - 2Output:
b = 0.1
print a, b
if a=b then print "Equal" else print "Not equal"
print "Difference "; a-b
0.1 0.1Instead, you should test for equality with given precision:
Not equal
Difference 0.83266727e-16
precision = 1e-10
if abs(a - b) < precision then print "Equal with precision" else print "Not equal"
- You should not make FOR loops with real step, if the number of steps is important (like in numerical integration).
for i = 1 to 2 step 0.1This example misses the last step (end up on 1.9 instead of 2.0).
print i
next
Instead, you should use loop by integer index.
Saving/loading real number
There is no way inThe problem is that PRINT outputs only 7 digits of 16 we could use. If we try VAL, we’ll see that it
The USING function
Using numbers as Booleans
As was stated,If we print result of any relational operator (> < = >= <= <>), we'll see that true prints as 1 and false prints as 0.
This explains construction like eternal loop:
While 1Also it opens possibilities for using a condition result as a
...
Wend
y=x*(x>0)(returns x if it is >0, otherwise 0)
The only official rule is " 0 represents false, everything else means true ".
That allows for things like
If instr(txt$,searchFor$) thenMeaning the same as
If instr(txt$,searchFor$)<>0 thenThat is, "if searchFor$ is found in txt$".
However
5 or 3 -> 7 (101 or 011 -> 111)You can examine bits in a number with finction BitPattern$:
5 and 3 -> 1 (101 and 011 -> 001)
5 xor 3 -> 6 (101 xor 011 -> 110)
function BitPattern$(num)So it is possible to get
for i = 0 to 31
if i mod 8 = 0 then BitPattern$ = " " + BitPattern$
BitPattern$ = str$((num and 2 ^ i) > 0) + BitPattern$
next i
end function
a=1:b=2resulting at
if a then print "a is true" else print "a is false"
if b then print "b is true" else print "b is false"
if a and b then print "a and b is true" else print "a and b is false"
a is true
b is true
a and b is false
Also note that some
Function NOT(x), contrary to logical operators, is not bitwise. It returns -1 for true, too. You can get bitwise NOT(x) as (x XOR -1) (it looks like -1 in binary representation has 32 bits set).
There are two exceptions to the rule "0 represents false, everything else means true":
1) Syntax of SELECT CASE allows conditions in CASE, but here only the value 1 is accepted as
x = 12) while real number like 0.1 is surely not 0, you cannot use reals instead of conditions. BASIC just dies at runtime with "isEmpty not understood" error.
select case
case x: print "true"
case else: print "false"
end select
'prints true
x = -1
select case
case x: print "true"
case else: print "false"
end select
'prints false
x = .1
if x then print "true" else print "false" ' dies at runtime with "isEmpty not understood" error.