Dejell
Dejell

Reputation: 14317

Math - mapping numbers java

I saw this question of mapping numbers algorithm.

I am trying to implement the @PeterAllenWebb solution in java like this:

long A = 1l;
long B =  999999999l;
long C = 1000000000l;
long D = 9999999999l;
long X =  999999998l;
long Y =   (D-C)*(X-A)/(B-A) + C;
System.out.println("original is " + X);     
long reverseX = (B-A)*(Y-C)/(D-C) + A;
System.out.println("reverse is " + reverseX);

However, this doesn't always work.

See below:

    X     reverseX
999999998 999999997
1         1
999999999 999999999
12        11

As you can see, only minimum (A) and maximum (B) are returning fine.

For the rest, I need to add 1. This seems to me as floor/round/Math issue and I don't want to rely on the JVM that calculates it. I would like it to always work.

How can I make the above work for reverseX?

Upvotes: 1

Views: 302

Answers (1)

Jayamohan
Jayamohan

Reputation: 12924

You are facing an age old issue. By default division is double in Java. So if your division result is 1.0 or 1.3 or 1.9 it will be truncated to 1. In your case the same is happening. Try changing it to double from long as below

double A = 1L;
double B = 999999999l;
double C = 1000000000l;
double D = 9999999999l;
double X = 999999998l;
double Y = (D - C) * (X - A) / (B - A) + C;

System.out.println("original is " + new DecimalFormat("#").format(X));
double reverseX = (B - A) * (Y - C) / (D - C) + A;
System.out.println("reverse is  "
        + new DecimalFormat("#").format(reverseX));

Upvotes: 1

Related Questions