Jump to content

Photo

Negative Number Rands

Library

  • Please log in to reply
7 replies to this topic

#1 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 01 September 2014 - 10:33 PM

I don;t recall if the Bison compiler can calculate a Rand with a negative number as an argument by default (as I've yet to need that ability), but an error that I saw in another post regarding producing a Rand with inappropriate arguments gave me pause for thought.

The compiler returned an error when trying to perform Rand(0), with a sqrt complaint; which may mean that Rand in Bison uses square roots to determine its randomising calculations; in which case, negative integers would be a rather large problem. (i.e. Imaginary, irrational numbers, like i.)

In the event that Rand doesn't permit negative vales as arguments (especially as zscript.txt states 'The return value is undefined if maxvalue is 0 or negative.'), in ZC, or in another compiler, here are two functions that should return results. The first, negRand produces a result from a negative value, to a positive value.

The second, negativeRand, produces a result between two negative values.

If these aren't necessary, then ignore this; bit I figured it'd be best to share them, as (at the least) they're creative mathematical functions, and NegativeRand may be useful in some applications where you only want irrational numbers as results.

I did some basic logistical analysis, with spreads of numbers, and they should produce the desired results with basic mathematics.
 
//Produces a Rand from a negative integer, to a positive integer.
//The result may be '0'.
//Use positive numbers as arguments.
// Usage: negRand(20, 10) produces a rand from -20 to +10.

int negRand(int neg, int pos){
    int sum = (pos+neg);
    int value = Rand(sum);
    int shift = neg;
    int total = ( value - shift );
    return total;
}


//Produces a random negative number, from -min to -max.
//Enter the arguments as positive numbers:
// NegativeRand(20,10) produces a result from -20 to -10

int NegativeRand(int lowest, int highest){
    int value = Rand(min,max);
    int shift = (0 - value - value);
    int total = value = shift;
    return total;
}

//Produces a floating point rand from negative value, to positive value. 
float negRandf(float neg, float pos){
    float sum = (pos+neg);
    float value = Rand(sum);
    float shift = neg;
    float total = ( value - shift );
    return total;
}

//Produces a floating point value as a negative number.
float NegativeRandf(float lowest, float highest){
    float value = Randf(min,max);
    float shift = (0 - value - value);
    float total = value = shift;
    return total;
}

//Produces a negative integer between minValue and 0.

int nRand(int minValue){
    int value = Rand(minValue);
    int shift = (0 - value - value);
    int total = value = shift;
    return total;
}


Edited by ZoriaRPG, 01 September 2014 - 11:13 PM.


#2 Gleeok

Gleeok

    It's dangerous to dough alone, bake this.

  • Members
  • Real Name:Pillsbury
  • Location:Magical Land of Dough

Posted 02 September 2014 - 02:56 AM

Whoa, whoa, whoa, whoa..whoa...... whoa.

is there a reason you're not just using int r = -Rand(-negvalue); ? Is there a bug somewhere? I'm not sure why you're getting a sqrt error. *curious* sqrt is not used at all.

Rand(min,max) should also work:
int n = Rand(-4,4); should produce an integral value between -4 and 4 inclusive.
float n = Randf(-4,4); should produce an decimal value between -4 and 4 inclusive.
So Rand(-4, 0); should return a value between -4, and 0.

Do any of those not work properly?
  • Mero likes this

#3 Mero

Mero

    Touch Fluffy Tail

  • Banned
  • Real Name:Tamamo No Mae
  • Location:Rainbow Factory

Posted 02 September 2014 - 03:00 AM

I had a similar problem when trying to get Rand(0) to return, so I assume randoms have to be positive. You can do this though.

 -Rand(x)

Edited by Freya, 02 September 2014 - 03:05 AM.


#4 Gleeok

Gleeok

    It's dangerous to dough alone, bake this.

  • Members
  • Real Name:Pillsbury
  • Location:Magical Land of Dough

Posted 02 September 2014 - 03:29 AM

Okay. Thanks ZoriaRPG.
Fixed the rand() function slightly. Rand(0); Rand(negativeInt); and Rand(positiveInt); all should work now.


[edit] Found the sqrt() error. The problem is that sqrt(-1) is imaginary, so usually negative values return nan or inf. However, in games you sometimes may want the square root of an unknown x,y coordinate somewhere, which might be negative or not. Usually this is not an issue, though, and is likely an error in the math of the script. So, I don't know what to do about it.

#5 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 02 September 2014 - 08:05 AM

Aye, I mentioned all of that in Freya's thread. (Sqrt of -1 is actually an imaginary, irrational number, as no negative number can have a square root; although cubic root is another matter, if it matters, to any rational, real person. Oh, the puns!)

The correct return for sqrt -x is: i, or j.

That however, would require defining i, or j as a valid return; particularly as in the C language, these are also commonly used declarations, especially for limited-use applications (e.g. for loops).

As I said, I wasn't certain if the in-built Rand functions handled this properly, so I tossed this in as aux functions, for use in the case of an imaginary emergency. (Mostly, because I could.)

I don't personally have a use for producing a value that ranges from a negative, to a positive value [a at present ], although one of my collaborators did in the past (for a very different type of RPG dynamic), and I only hazily recall some sort of problem.

I wasn't certain if Rand would accept a single negative value ( e.g. Rand(-15) ), but I believe that it wouldn't; and as long as I was addressing that, adding the other functions that convert positive values into parsed negative values with shifting, or compounded subtraction was a good way to waste five minutes.

At least it caught your attention, and will be fixed in a future update. Was that allegro error just a bad report, or an actual problem with the way that the function works?

I'm a bit curious on the randomisation algorithm in ZC, as I've noticed at least a slight bias with large number spreads (e.g. 1 to 100), with specific favourability towards umber sets. I tried to make special tables to force-balance that, but for all I know, it's CPU-specific, or architecture-specific..

It's a pain to produce, and analyse a proper sample size.

Thank you for addressing whatever needed tightening.

Edited by ZoriaRPG, 02 September 2014 - 08:13 AM.


#6 Gleeok

Gleeok

    It's dangerous to dough alone, bake this.

  • Members
  • Real Name:Pillsbury
  • Location:Magical Land of Dough

Posted 02 September 2014 - 08:56 PM

From what I heard from Freya, the Sqrt() errors comes from a ghost.zh function that calls Sqrt(). The Rand() function simply calls the standard cmath rand() function which is usually something like this:
inline int rand() {
		return(((rand_seed = rand_seed * 214013 + 2531011) >> 16) & RAND_MAX);
	}
The script rand is also shared by ZC code as well, so getting a rand every frame would likely produce different results than getting a bunch in a for loop, since enemy movement, for example, use rand up the wazoo. so, the results may be, well...random. :P

#7 Mero

Mero

    Touch Fluffy Tail

  • Banned
  • Real Name:Tamamo No Mae
  • Location:Rainbow Factory

Posted 03 September 2014 - 03:52 AM

Actually I had Saffith look into it. And he told me that it's that scripted weapons have no limits on how far they go can off screen. ;)



#8 Timelord

Timelord

    The Timelord

  • Banned
  • Location:Prydon Academy

Posted 03 September 2014 - 11:18 AM

Actually I had Saffith look into it. And he told me that it's that scripted weapons have no limits on how far they go can off screen. ;)


I learnt that while scripting brang-style items, that allowed multiple projectiles if the player had special items. I would assume there'd be some boundary,c but I'd also be wrong. The interesting thing is that (in theory) you could script a weapon, or ffc that leaves the screen, that Link could 'catch up' to, by using adjustments to its position based on moving between screens. Not easy to accomplish, but possible, in theory.



Also tagged with one or more of these keywords: Library

1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users