Oxygen Basic
Programming => Bugs & Feature Requests => Topic started by: Mike Lobanovsky on May 14, 2014, 03:38:46 AM
-
Hi Charles,
Please download my zip from here (http://www.oxygenbasic.org/forum/index.php?topic=1032.msg8680#msg8680). It contains an Oxygen script and an executable.
While the exe precompiled with an earlier version of Oxygen displays correct results, integer math and/or logic in the raw script run with the latest Oxygen as of May 13 seem to be broken.
:-\
.
-
Hi Mike,
This was caused by a correction for calculating divisions: OxygenBasic performs float divisions to get the most accurate (up or down) rounding on all types. This accords with other math functions like tan or log
When I changed all the '/' to '\' for explicit integer division, the results agree with yours.
Thanks for reporting the problem! Do you agree or disagree with O2's division policy?
.
-
Charles, ???
It seems to me certainly not consistent with what we have in the C language and all other BASIC's out there that support strong type variables. I'm dividing integer products by integer literals all the way through the code: these are integer 100's and 200's, not float 100.'s and 200.'s. That's why there should be integer division despite the forward slash.
int x = 1, y = 1, z;
z = (double)(x * y) / 1; // floating point division
z = (x * y) / 1.0; // ditto
z = (x * y) / 1; // integer division!
Oxygen's math risks becoming incompatible with conventional practices... :-\
-
Then I am happy to change this policy, it will make compiling a little simpler :)
Any objections, anyone ?
-
Any objections, anyone ?
Yes,
Math is okay.
-
Yes,
Math is okay.
Hmmm, which math of the two is OK, please? :-\
-
don't worry Mike,
he will alter it in any case!
-
If SB being around for over 14 years and not declaring any variable types means anything, I think Charles is just following traditional BASIC good practices. The following is Charles's code with a couple return to BASIC syntax changes.
accum = 0
count = 0
while (count < 1545)
left_edge = -420
right_edge = 300
top_edge = 300
bottom_edge = -300
x_step = 7
y_step = 15
max_iter = 200
y0 = top_edge
while (y0 > bottom_edge)
x0 = left_edge
while (x0 < right_edge)
y = 0
x = 0
the_char = 32
x_x = 0
y_y = 0
i = 0
while (i < max_iter AND x_x + y_y <= 800)
'all integer divisions \
x_x = (x * x) \ 200
y_y = (y * y) \ 200
if (x_x + y_y > 800 ) then
the_char = 48 + i
if (i > 9) then
the_char = 64
end if
else
temp = x_x - y_y + x0
if ((x < 0 AND y > 0) OR (x > 0 AND y < 0)) then
y = (-1 * ((-1 * (x * y)) \ 100)) + y0
else
y = x * y \ 100 + y0
end if
x = temp
end if
i = i + 1
wend
accum = accum + the_char
x0 = x0 + x_step
wend
y0 = y0 - y_step
wend
if count % 300 = 0 then
print accum, "\n"
end if
count = count + 1
wend
print accum,"\n"
jrs@laptop:~/sb/sb22/test$ scriba intman.sb
200574
60372774
120544974
180717174
240889374
301061574
309886830
jrs@laptop:~/sb/sb22/test$
-
Thanks for your reply, Peter.
Charles, please hold on for a while! I'm experimenting...
John, his previous O2 worked equally well with both / and \. I'm yet experimenting, please hold on. That's not a matter of returning, that's a matter of tradition and precision too.
-
Here is the same code but not doing integer division.
accum = 0
count = 0
while (count < 1545)
left_edge = -420
right_edge = 300
top_edge = 300
bottom_edge = -300
x_step = 7
y_step = 15
max_iter = 200
y0 = top_edge
while (y0 > bottom_edge)
x0 = left_edge
while (x0 < right_edge)
y = 0
x = 0
the_char = 32
x_x = 0
y_y = 0
i = 0
while (i < max_iter AND x_x + y_y <= 800)
x_x = (x * x) / 200
y_y = (y * y) / 200
if (x_x + y_y > 800 ) then
the_char = 48 + i
if (i > 9) then
the_char = 64
end if
else
temp = x_x - y_y + x0
if ((x < 0 AND y > 0) OR (x > 0 AND y < 0)) then
y = (-1 * ((-1 * (x * y)) / 100)) + y0
else
y = x * y / 100 + y0
end if
x = temp
end if
i = i + 1
wend
accum = accum + the_char
x0 = x0 + x_step
wend
y0 = y0 - y_step
wend
if count % 300 = 0 then
print accum, "\n"
end if
count = count + 1
wend
print accum,"\n"
jrs@laptop:~/sb/sb22/test$ scriba intmandiv.sb
201086
60526886
120852686
181178486
241504286
301830086
310677870
jrs@laptop:~/sb/sb22/test$
OxygenBasic - latest build
Integer DIV
Starting Mandel accum:
200574
60372774
120544974
180717174
240889374
301061574
309886830
Time: 7.5689999999999999 Seconds
Standard DIV
Starting Mandel accum:
200849
60455549
120710249
180964949
241219649
301474349
310311705
Time: 8.6679999999999993 Seconds
-
@Charles:
It seems like FB and PB that IMHO should be taken as the criteria show a tendency towards your approach though their precision (i.e. method of rounding) is certainly different. They do show different (but equal among themselves!) results for / and \. These results are not however the same as adding floating point divisors in C instead of integer ones ... :-\
Yet my alert wasn't altogether in vain. Hmmm, let's stick to FB and PB if we can?
@John:
Compare your scriba floating point division output and similar O2 output in your message or in the picture below - they don't match:
.
-
Okay, we will keep division behaviour as it is now. The integer division operator '\' does the job whenever you require it.
OxygenBasic has a degree of auto-polymorphism between integers and floats ( and strings too), so the bias towards float division is important for the system as a whole.