How to clamp a value from 0 to infinite to a value from 0 to 1?
Asked Answered
S

5

7

I have a program in Java that generates a float value aggressiveness that can be from 0 to infinite. What I need to do is that the higher this float is, the higher there are chances the program fires a function attackPawn().

I already found out that I need the function Math.random(), which gives a random value between 0 and 1. If Math.random() is lower than aggressiveness transformed into a float between 0 and 1, I call the function attackPawn().

But now I am stuck, I can't figure out how I can transform aggressiveness from 0 to infinite to a float which is from 0 to 1, 1 meaning "infinite" aggressiveness and 0 meaning absence of anger.

Any ideas or math equation?

Successful answered 16/4, 2014 at 9:44 Comment(6)
As infinity is really finite (at least on hardware used nowadays) you could simply divide aggressiveness by Float.MAXVALUE.Inseminate
@DirkLachowski This is a very limited approach since bijections for this problem exist, e.g. tan(x*pi/2)Hypochondriasis
It would be really helpful if you post some code, whatever you have tried..Fencer
@Hypochondriasis Sure, but im not sure if mathmatical correctness is needed for an aggressiveness metric in a game - and for a game it should be more fast than exact...Inseminate
@DirkLachowski You are correct, correctness is not needed. But if the question is to fulfill a definition then correctness is needed. (Yet it would be better to change the definition)Hypochondriasis
@Hypochondriasis I agree, but there is no evidence in the question that it has to be a linear transformation. But as you suggested changing the definition of aggressiveness should be the way to go.Inseminate
K
23

You want a monotonic function that maps [0...infinity] to [0..1]. There are many options:

    y=Math.atan(x)/(Math.PI/2);
    y=x/(1+x);
    y=1-Math.exp(-x);

There are more. And each of those functions can be scaled arbitrarily, given a positive constant k>0:

    y=Math.atan(k*x)/(Math.PI/2);
    y=x/(k+x);
    y=1-Math.exp(-k*x);

There is an infinite number of options. Just pick one that suits your needs.

Kerosene answered 16/4, 2014 at 9:55 Comment(0)
H
2

It is possible to map [0,infinity) to [0,1), but this won't be linear. An example function would be:

y = tan(x * pi / 2);

The problem with this function is that you can't make a correct computer program from that since it is not possible (or easy) to first compute a real big number like 10^5000 and map it down to [0,1).

But a better solution would be to change your definition to something like that:

0 = no aggression
1 = maximum aggression

With this you don't have to map the numbers

Hypochondriasis answered 16/4, 2014 at 9:57 Comment(0)
E
1

Try something like this:

// aggressiveness is a float with a value between 0 and Float.MAX_VALUE or a value of Float.POSITIVE_INFINITY
if (aggressiveness == Float.POSITIVE_INFINITY) {
    aggressiveness = 1f;
} else {
    aggressiveness = aggressiveness / Float.MAX_VALUE;
}
// aggressiveness is now between 0 and 1 (inclusive)
Estrange answered 16/4, 2014 at 9:56 Comment(0)
E
0

Though Double class supports infinite value double d=Double.POSITIVE_INFINITY but i dont think you can use it for your arithmatic purpose. Better you define a maximum value and treat it as infinity.

double Min=0;
double Max= Double.MAX_VALUE;

double aggresiveness= Min + (Math.random() * ((Max - Min) + 1));

ps: you can also take aggresiveness as long or int if you don't want it be a double

Exciting answered 16/4, 2014 at 10:0 Comment(0)
E
-1

Try to transform aggressiveness with a function like:

public float function(float aggressiveness) {
    if(aggressiveness > 0F) {
        return 1 - (1 / aggressiveness);
    }
    return 0F;
}

This will map your value to the range of [0, 1);

Elli answered 16/4, 2014 at 9:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.