How to convert a float scale to long scale? - java

I have two scales,one is x-value scale,with float values which starts from minimum x value and ends at maximum x value.I call these values as min_x and max_x.
I have another scale with long value which starts from 0 and ends at maximum time value,i call it max_tim value.
how do i convert a float xvalue into corresponding long time value?
I have tried something on android studio but i am getting incorrect values.
private long max_tim,tim;
private float min_x,max_x,x_val;
tim=((long)((x_val-min_x)/(max_x-min_x)))*max_tim;
I have got correct values of tim for max_x and min_x but not for the values in between.I think i have correct logic but think its faulty typecasting.Please help me out.

float range = max_x - min_x; // get the absolute range of the first scale
float offset = x_val - min_x; // normalize the value on the first scale to the absolute range
tim = (long)((offset*max_tim)/range); // convert to the new scale, which is already in absolute values
For example, if your x-value scale is in farenheit and ranges from 32.0 - 212.0. And your "long scale" is in centigrade from 0-100. And you wanted to convert 50 degrees Farenheit to centigrade
range = 212-32; // 180
offset = 50-32; // 18
tim = (18*100)/180 = 10;
50°F == 10° C

Related

Java to map a range of float values to graphical display

I want to take a range of float values (subject) that change and map them on to a static range of colours 0 - 255 for displaying on the screen.
The subject range of values start with the float being a minimum of 0.056582272 to the largest 0.34371486
when running calculation changes overtime to a minimum of 0.0791025 to the largest 4.5757337
If I map them using
number / 255 * largest
which in code is
thecol=elements[x][y][subject]*255/largest;
You see the colours at the beginning when I pop them on the screen, then at the end but nothing in between.
You did not factor in the minimum of the range for your calculation.
float rangeSize = largest - smallest;
float mappedTo0to1 = (value - smallest) / rangeSize; // Map to range 0 - 1.
int mappedResult = (int) (mappedTo0to1 * 255); // Map to range you want. (0 - 255).
The trick with verifying these kind of functions is to look at the lowest and highest input values possible.

How to clamp a value from 0 to infinite to a value from 0 to 1?

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?
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.
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
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)
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
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);

Randomly generating floats spanning the whole spectrum of valid floats

As part of random testing, I'm looking to generate random floats spanning the whole spectrum of valid floats (but excluding +/- infinity and NaN). I want very, very large numbers and minuscule numbers, both positive and negative.
Here's what I'm doing:
Random r = new Random();
float random_value = (r.nextFloat() - 0.5f) * Float.MAX_VALUE;
This seems like it should in theory work, but it only generates very large values. (ie. in the range of 1037 – 1038, positive and negative)
Any suggestions?
Your code should create uniformly distributed float values, that is, a uniform distribution in a purely mathematical sense. However, most of these values will be in the 1037-1038 range, simply because there are more mathematical values in that range than in the lower, everyday value range. In the real domain, there are 10 times as many values in the range 1037-1038 as 1036-1037, 10 times as many values in the range 1036-1037 as 1035-1036, and so on, so it's no surprise that just about all of them are of extremely large magnitude.
What I think you want is a completely random float value, with a range only in the valid float domain. Because a float is specified by an exponent and a mantissa, the limiting factor as to how many values are available in a given range is limited by the precision, not how many mathematical values are available. Specifically, there are precisely the same number of float values between a and b as there are between 2 * a and 2 * b, provided all values are within the float domain.
There is a one-to-one correspondence between all possible int values and all possible float values (including infinities and NaN), because both primitive types are represented by 32 bits.
Choose a random int value, across all possible int values, positive, 0, and negative, and convert the bit representation of the int to the corresponding bit representation of the float you want. You'll have to choose a random long and downcast to int. If you randomly get an infinity or an NaN, try again.
Random rnd = new Random();
float randomFloat = 0.0f;
do {
// downcast will cover negative int value range.
int randomInt = (int) rnd.nextLong(1L << 32);
float randomFloat = Float.intBitsToFloat(randomInt);
// Discard infinities and NaNs.
} while (randomFloat == Float.NEGATIVE_INFINITY ||
randomFloat == Float.POSITIVE_INFINITY ||
Float.isNaN(randomFloat));
You can get an uniform distribution by generating your floats using bits instead of arithmetic.
This could be an option:
public static float randomFloat() {
// Generate a random integer. These are uniform over the 32 bit words
Random r = new Random();
int intBits = r.nextInt();
// Make a float from the integer's bits
float f = Float.intBitsToFloat(intBits);
// Handle non-numeric cases
if (Float.isInfinite(f) || Float.isNaN(f)) {
// Only happens ~ 1/250 times
return randomFloat();
} else {
return f;
}
}
You are probably hitting precision issues. Try doing the multiplication at double precision and then casting down to a float afterwards.
i.e.
float random_value = (float)((r.nextDouble() - 0.5) * Float.MAX_VALUE);
Firstly you want to generate a random float between -1 and 1. To do this:
Random r = new Random();
float random_value = r.nextFloat() * 2 - 1
and then scale that:
Random r = new Random();
float random_value = (r.nextFloat() * 2 - 1) * Float.MAX_VALUE

Convert from Float to integer

I built a simple Android "accelerometer" Sensor Application.
This is The Java Code link.
The output is like this:
X:8.87654322
Y:0.564321
Z:4.0195783
And sometimes it goes longer ...
I want to convert the float to an integer or just have 2 numbers
(I'm a beginner In Java.)
Thanks
double y = 9.37923929732232;
int a = (int)y;
double d = 4.232
int answer = (int) Math.round(d);
i think you want to convert float array values of accelerometer to int below is the float array with two float values i am just rounding off the value of float element of oth index using Math.round(arrayname[indexnumber])
float[] fArray = new float[] {(float) 6574.748, (float) 789.999};
int f1 = Math.round(fArray[0]);
System.out.println(f1);
this will round off the float value for ex 6574.748 will be rounded to 6575
To convert float sensor data to integer you have to mutiply them, and then round.
e.g you want 1 digit after comma. 0.56432 -> 6
double y = 0.564321;
int yi = (int) Math.Round(y * 10); // for taking 2 digits after comma use 100
Then you have handy acceleration sensor data.
For getting two decimal places use (java.text.DecimalFormat:)
You can try this
double roundTwoDecimals(double d) {
DecimalFormat twoDForm = new DecimalFormat("#.##");
return Double.valueOf(twoDForm.format(d));
}
For integer there are other answers in the post.

How can I show up to 2 decimal places without rounding off?

I want to take two decimal places only for a float without rounding off. eg. 4.21777 should be 4.21 and not 4.22. How do I do this?
A simple answer:
double x = 4.21777;
double y = Math.floor(x * 100) / 100;
Subtract 0.005 and then round. For example if you just want to print the number you can use a format of %f6.2 and the value x-0.005.
float f = 4.21777 * 100;
int solution = (int)f;
f = solution/100;
This should work ;)
Explanation: By multiplying with 100, you will get 421.777, which, castet to int, is being rounded down to 421. Now divided by 100 returns its actual value.

Categories