0

Does there exist, or can you create, a fast method A() which converts a double to a long such that:

A(0d) = 0L
A(Math.nextUp(0d)) = 1L
A(Math.nextUp(Math.nextUp(0d))) = 2L
A(Math.nextUp(Math.nextUp(Math.nextUp(0d)))) = 3L
...
A(Double.MAX_VALUE) = Long.MAX_VALUE
A(-Double.MAX_VALUE) = -Long.MAX_VALUE

EDIT: Just found an adequate answer myself. First of all the above is not quite possible due to the existence of NaN and infinity for double. The fact that Long does not have these means that Long.MAX_VALUE is larger than the amount of double bit permutations that create actual numbers. However, despite this my usecase is actually just that I want a conversion that maps double to long while being order-preserving. As long as I don't encounter NaN or infinity I guess I should be able to just reinterpret double to long.

Double.doubleToLongBits(value)
Runekn
  • 85
  • 5
  • What did you try? – JCWasmx86 Jan 29 '21 at 13:02
  • @JCWasmx86 Not much. The only thing I have thought of is an iterative loop that does pretty much what I did in post until it gets to the value. But this is of course far from a fast method. What I was hoping was that someone with better than surface level insight into the structure of floating-point number could say whether you can manipulate or rearrange the bytes to achieve the desired in O(1). – Runekn Jan 29 '21 at 13:13
  • Actually, I think I just figured it out. I had also thought of simply interpreting the bits as a long but for some reason I convinced myself that it wouldn't work. But now I am thinking it actually would. – Runekn Jan 29 '21 at 13:17

1 Answers1

0

Math.nextUp() will increase the fractional part not the whole part. To get the desired output, you have to call a() for each Math.nextUp().

public class D2L {

    public static  Long a(double input) {
        return Math.round(Math.ceil(input));
    }

    public static void main(String[] args) {
        
        System.out.println(a(0d)); //0L
        System.out.println(a(Math.nextUp(a(0d)))); //1L
        System.out.println(a(Math.nextUp(a(Math.nextUp(a(0d)))))); //2L
        System.out.println(a(Math.nextUp(a(Math.nextUp(a(Math.nextUp(a(0d)))))))); //3L
        System.out.println(a(Double.MAX_VALUE) + " = " +Long.MAX_VALUE); //9223372036854775807 = 9223372036854775807
        System.out.println(-a(Double.MAX_VALUE) + " = " + -Long.MAX_VALUE); //-9223372036854775807 = -9223372036854775807
    }
}
  • Thanks for the answer. But I am not misinterpreting Math.nextUp. So this does not answer my question. But check out my edit as I think I have found it myself. – Runekn Jan 29 '21 at 13:50