Square Root
Yeah... I'm working on this project now that is requiring me to use the distance formula. Is there any way to get the square root of something in DinkC?
Heh...if there is anyone here that is really good at math and DinkC that wants to help me out with this, your assistance would be greatly appreciated. Like having your name in the credits 50x appreciated. LoL
Are you allowed to raise something to a power in DinkC? If so, use x^(1/2).
Hm...well is there any way to implement the distance formula without using a sq rt?
Well to raise to a power, you'd be multiplying something by itself a number of times.
Let's say the power you want to raise it to is x.
int &x = 4;
loop:
if (&x > 1)
{
&var *= &var;
&x -= 1;
goto loop
}
Thus &var is now &var^4
It's been a while since I wrote this stuff, so it may not be exactly right, but you get the idea.
So if you want to find the square root of a distance (to use the distance formula) I'm not sure if there's a way you could do it other than guess and check...
I'm tempted to say the best way to do it may just be to have ranges, because that's how it'll end up in the end since you can't use variables. What you'd do here is know that the range of 1 is 1 to 1 (well, not really a range I guess) and 2 is 2-4 and 3 is 3-9 and so on, finding what range it's in via simple subtraction would be quite easy.
If you're nit picky and you actually need those decimals to get this to work, you'd have to multiply you're distances by 100000 and you could have 6 decimal places. To find it this way, though, you'd have to set up a guess and check system:
&d = 100;
//I trust you can find the distance on your own by subtracting x's and y's
&d-carry = &d;
//just so we don't mess up &d
&var1 = 1;
//var1 will be the square root we're checking
&var1-carry = &var;
//this'll just keep us from messing with &var1
&var2 = 2;
&var2-carry = 2;
&checker;
//we'll use this at the end to check (duh)
//ok wow, i started making a formula where you could do it with anything, not just square roots, and decided it was too complicated... how about just square roots this time.
check:
&var1-carry = &var1;
&var1-carry *= &var1-carry;
&var2 = &var1;
&var2 += 1;
&var2-carry = &var2;
&d-carry = &d;
&d-carry -= &var2;
if (&d-carry < 0)
{
//var2 was too much, use var1
goto next;
}
&var1 += 1;
goto check;
//ok stop for now, i'm not sure of a few things. i'm not sure that it'll go into negatives easily like this. also, this is likely not the most efficient way. meh. this is all basically if you're too lazy to just do a simple range method like i mentioned earlier. in fact, i dunno why i wrote that, just use ranges. really the only good way i can think of is to use the range system (or the more one above, which may be easier on the engine) to find the range, for instance the square root of 27 is between 5-6, you know that because 6 is too much, and you are left with &var1 = 5. Thus, if you multiply the distance by 1000000 you can narrow it down further and further with guess and check like this, depending on how much you want to code and how exact you want it to be...
wait... now for a question i should have asked a long time ago...
wtf do you need a distance formula for? i'll bet you can work around having to use it much easier than bothering to write a long enough script to check decimals into the variable.
Let's say the power you want to raise it to is x.
int &x = 4;
loop:
if (&x > 1)
{
&var *= &var;
&x -= 1;
goto loop
}
Thus &var is now &var^4
It's been a while since I wrote this stuff, so it may not be exactly right, but you get the idea.
So if you want to find the square root of a distance (to use the distance formula) I'm not sure if there's a way you could do it other than guess and check...
I'm tempted to say the best way to do it may just be to have ranges, because that's how it'll end up in the end since you can't use variables. What you'd do here is know that the range of 1 is 1 to 1 (well, not really a range I guess) and 2 is 2-4 and 3 is 3-9 and so on, finding what range it's in via simple subtraction would be quite easy.
If you're nit picky and you actually need those decimals to get this to work, you'd have to multiply you're distances by 100000 and you could have 6 decimal places. To find it this way, though, you'd have to set up a guess and check system:
&d = 100;
//I trust you can find the distance on your own by subtracting x's and y's
&d-carry = &d;
//just so we don't mess up &d
&var1 = 1;
//var1 will be the square root we're checking
&var1-carry = &var;
//this'll just keep us from messing with &var1
&var2 = 2;
&var2-carry = 2;
&checker;
//we'll use this at the end to check (duh)
//ok wow, i started making a formula where you could do it with anything, not just square roots, and decided it was too complicated... how about just square roots this time.
check:
&var1-carry = &var1;
&var1-carry *= &var1-carry;
&var2 = &var1;
&var2 += 1;
&var2-carry = &var2;
&d-carry = &d;
&d-carry -= &var2;
if (&d-carry < 0)
{
//var2 was too much, use var1
goto next;
}
&var1 += 1;
goto check;
//ok stop for now, i'm not sure of a few things. i'm not sure that it'll go into negatives easily like this. also, this is likely not the most efficient way. meh. this is all basically if you're too lazy to just do a simple range method like i mentioned earlier. in fact, i dunno why i wrote that, just use ranges. really the only good way i can think of is to use the range system (or the more one above, which may be easier on the engine) to find the range, for instance the square root of 27 is between 5-6, you know that because 6 is too much, and you are left with &var1 = 5. Thus, if you multiply the distance by 1000000 you can narrow it down further and further with guess and check like this, depending on how much you want to code and how exact you want it to be...
wait... now for a question i should have asked a long time ago...
wtf do you need a distance formula for? i'll bet you can work around having to use it much easier than bothering to write a long enough script to check decimals into the variable.
Try this:
int &mynumber;
int &f1 = 3;
int &f2;
int &avg;
int ÷
int &sqroot;
//assign a value to the &mynumber variable
&mynumber = //how ever you get this
&f2 = &mynumber;
&f2/&f1;
loop:
&avg = &f1;
&avg += &f2;
&avg / 2;
&div = &mynumber;
&div/&avg;
&f1 = ÷
&f2 = &avg;
if (&f1 < &f2) goto loop;
&sqroot = &f1;
&sqroot += &f2;
&sqroot / 2;
//Now the value in &sqroot should be (at least close to as an integer) the square root of &mynumber.
I've not tested this... but it should work
int &mynumber;
int &f1 = 3;
int &f2;
int &avg;
int ÷
int &sqroot;
//assign a value to the &mynumber variable
&mynumber = //how ever you get this
&f2 = &mynumber;
&f2/&f1;
loop:
&avg = &f1;
&avg += &f2;
&avg / 2;
&div = &mynumber;
&div/&avg;
&f1 = ÷
&f2 = &avg;
if (&f1 < &f2) goto loop;
&sqroot = &f1;
&sqroot += &f2;
&sqroot / 2;
//Now the value in &sqroot should be (at least close to as an integer) the square root of &mynumber.
I've not tested this... but it should work
Thanks a lot for the help guys, I'll work on implementing this as soon as I get home today. Meh... I need to get better at math.

Hmm...not to be naggy, but something seems to be wrong with the code: I put 4 in and it got 3 and I put 16 in and it got 12...LoL. Sorry, I'd try to figure it out myself but im not good at math...especially when its evil DinkC math.

It doesn't work for me either.
You could always use the brute force method if the numbers aren't too big:
int &testit;
int &answer = 0;
int &mynumber = 73; //whatever
loop: &answer += 1;
&testit = &answer;
&testit *= &testit;
if (&testit < &mynumber)
goto loop;
say("The answer, rounded up, is &answer", 1);
Or if you'd rather round down, start &answer at the highest value you anticipate, use -= and test for > &mynumber. Obviously it will have to be rounded since the squere root of most numbers is a faction and Dink only does intigers.

int &testit;
int &answer = 0;
int &mynumber = 73; //whatever
loop: &answer += 1;
&testit = &answer;
&testit *= &testit;
if (&testit < &mynumber)
goto loop;
say("The answer, rounded up, is &answer", 1);
Or if you'd rather round down, start &answer at the highest value you anticipate, use -= and test for > &mynumber. Obviously it will have to be rounded since the squere root of most numbers is a faction and Dink only does intigers.
Okay here it goes... I've tested this as key-80.c and Dink tells me the right answer for the tests of 4, 9, 16, 25, 400, 10000... and I'm assuming 123456789
....
//Sqaure Root
void main( void )
{
int &mynumber;
int &guess = 3;
int &avg;
int ÷
int &chk1;
int &chk2;
int &sqroot;
int &countloop;
int &disploop;
freeze(1);
newtest:
&countloop = 0;
int &guess = 3;
//assign a value to the &mynumber variable
choice_start()
"Test 4"
"Test 9"
"Test 16"
"Test 25"
"Test 144"
"Test 400"
"Test 10000"
"Test 123456789"
choice_end();
if (&result == 1)
&mynumber = 4;
if (&result == 2)
&mynumber = 9;
if (&result == 3)
&mynumber = 16;
if (&result == 4)
&mynumber = 25;
if (&result == 5)
&mynumber = 144;
if (&result == 6)
&mynumber = 400;
if (&result == 7)
&mynumber = 10000;
if (&result == 8)
&mynumber = 123456789;
debug("Starting new test for &mynumber");
calroot:
debug("Calroot has started run &countloop + 1");
debug("Guess is &guess");
&div = &mynumber;
debug("divide is now &div which should be &mynumber");
&div / &guess;
debug("divide is now ÷");
&avg = &guess;
debug("average is now &avg which should be &guess");
&avg += ÷
debug("average is now &avg which should be &guess plus &div");
&avg / 2;
debug("average is now &avg ... old one divided by 2");
debug("guess is still &guess");
&countloop += 1;
debug("loop passed thru is &countloop");
//next line is just to see how many times it takes to get to an answer
say_stop_xy("`5GONE THRU LOOP &countloop TIMES", 10, 40);
//remove this line to speed up the calcualtions
// wait(1000);
if (&guess == &avg)
{
debug("We are here if &guess equals &avg");
goto getoutofloop;
} else
{
debug("We are here to figure out if guess and average are close");
debug("Guess is &guess, Average is &avg");
&chk1 = &guess;
&chk1 -= &avg;
if (&chk1 == 1)
goto getoutofloop;
&chk2 = &avg;
&chk2 -= &guess;
if (&chk2 == 1)
goto getoutofloop;
debug("If we are here, then the difference between guess and average is more than one");
debug("so now guess becomes the old average");
&guess = &avg;
&disploop = get_sprite_with_this_brain(8, 0);
sp_kill(&disploop, 1);
goto calroot;
}
getoutofloop:
debug("finished calroot loop");
&sqroot = &avg;
say_stop("`5The Sqaure Root of &mynumber is &sqroot", 1);
choice_start()
"Another Test"
"Leave"
choice_end();
if (&result == 1)
goto newtest;
unfreeze(1);
kill_this_task();
}
....
//Sqaure Root
void main( void )
{
int &mynumber;
int &guess = 3;
int &avg;
int ÷
int &chk1;
int &chk2;
int &sqroot;
int &countloop;
int &disploop;
freeze(1);
newtest:
&countloop = 0;
int &guess = 3;
//assign a value to the &mynumber variable
choice_start()
"Test 4"
"Test 9"
"Test 16"
"Test 25"
"Test 144"
"Test 400"
"Test 10000"
"Test 123456789"
choice_end();
if (&result == 1)
&mynumber = 4;
if (&result == 2)
&mynumber = 9;
if (&result == 3)
&mynumber = 16;
if (&result == 4)
&mynumber = 25;
if (&result == 5)
&mynumber = 144;
if (&result == 6)
&mynumber = 400;
if (&result == 7)
&mynumber = 10000;
if (&result == 8)
&mynumber = 123456789;
debug("Starting new test for &mynumber");
calroot:
debug("Calroot has started run &countloop + 1");
debug("Guess is &guess");
&div = &mynumber;
debug("divide is now &div which should be &mynumber");
&div / &guess;
debug("divide is now ÷");
&avg = &guess;
debug("average is now &avg which should be &guess");
&avg += ÷
debug("average is now &avg which should be &guess plus &div");
&avg / 2;
debug("average is now &avg ... old one divided by 2");
debug("guess is still &guess");
&countloop += 1;
debug("loop passed thru is &countloop");
//next line is just to see how many times it takes to get to an answer
say_stop_xy("`5GONE THRU LOOP &countloop TIMES", 10, 40);
//remove this line to speed up the calcualtions
// wait(1000);
if (&guess == &avg)
{
debug("We are here if &guess equals &avg");
goto getoutofloop;
} else
{
debug("We are here to figure out if guess and average are close");
debug("Guess is &guess, Average is &avg");
&chk1 = &guess;
&chk1 -= &avg;
if (&chk1 == 1)
goto getoutofloop;
&chk2 = &avg;
&chk2 -= &guess;
if (&chk2 == 1)
goto getoutofloop;
debug("If we are here, then the difference between guess and average is more than one");
debug("so now guess becomes the old average");
&guess = &avg;
&disploop = get_sprite_with_this_brain(8, 0);
sp_kill(&disploop, 1);
goto calroot;
}
getoutofloop:
debug("finished calroot loop");
&sqroot = &avg;
say_stop("`5The Sqaure Root of &mynumber is &sqroot", 1);
choice_start()
"Another Test"
"Leave"
choice_end();
if (&result == 1)
goto newtest;
unfreeze(1);
kill_this_task();
}
February 3rd 2004, 03:29 PM

uberpizza


....and SimonK is in the credits 10,000,000 times LoL. Thanks a lot!