Reputation: 14317
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
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