1

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?

Community
  • 1
  • 1
Dejell
  • 13,947
  • 40
  • 146
  • 229

1 Answers1

1

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));
Jayamohan
  • 12,734
  • 2
  • 27
  • 41
  • This doesn't work well. Since let's set String result = new DecimalFormat("#").format(Y); and then instead of double reverseX = (B - A) * (Y - C) / (D - C) + A; it will be double reverseX = (B - A) * (Double.praseDouble(result) - C) / (D - C) + A; it won't be accurate as format rounds the result. Your code works only if both are double – Dejell Feb 20 '13 at 09:50