Unsigned long to double and back

Remi Forax forax at univ-mlv.fr
Fri Nov 11 15:49:40 UTC 2022


Hi all, 
I don't know if it's the correct way to do it or if there is a better way, but i'm using 

var result = (double) (value & 0x7fffffffffffffffL ); 
if (value < 0) { 
result = result + 9.223372036854776E18; 
} 

The idea is to mask the sign bit, do the conversion to double and if the sign bit was present (if value < 0) add Long.MAX_VALUE + 1 (9223372036854775808) as a double. 

I've got 9.223372036854776E18 as the result of 
BigInteger.valueOf(Long.MAX_VALUE).add(BigInteger.ONE).doubleValue() 

Rémi 

> From: "David Lloyd" <david.lloyd at redhat.com>
> To: "Johannes Kuhn" <info at j-kuhn.de>
> Cc: "core-libs-dev" <core-libs-dev at openjdk.java.net>
> Sent: Friday, November 11, 2022 3:38:31 PM
> Subject: Re: Unsigned long to double and back

> Well, I typed this out from memory so there's an error, of course. `(tmp & 1)`
> should be `(input & 1)`.

> On Fri, Nov 11, 2022 at 8:31 AM David Lloyd < [ mailto:david.lloyd at redhat.com |
> david.lloyd at redhat.com ] > wrote:

>> I encountered this issue as well; for now I'm using the following
>> transformation:

>> long tmp = input >>> 1;
>> double output = ((double) tmp) * 2.0 + (tmp & 1);

>> I... *think* it's correct but I'm not 100% sure and have a long-standing TODO to
>> try and figure it out...

>> On Sat, Nov 5, 2022 at 7:17 PM Johannes Kuhn < [ mailto:info at j-kuhn.de |
>> info at j-kuhn.de ] > wrote:

>>> When I tried to implement an WASM transpiler, I noticed some missing
>>> conversion methods from unsigned types to floating point, for example
>>> from unsigned long to a double.

>>> For the meaning of unsigned long, see Long.toUnsignedString(long i).

>>> Converting between unsigned long and floating point is not a trivial
>>> task, as it probably requires some bit manipulation.

>>> In particular, I would love to see the following methods added*:

>>> - double Double.fromUnsignedLong(long i)
>>> - long Double.toUnsignedLong(double d)
>>> - float Float.fromUnsignedLong(long i)
>>> - long Float.toUnsignedLong(float f)

>>> * Subject to bikeshedding - I don't care about the name, or if it is
>>> added to the Long class.

>>> Currently, I don't think that additional methods for unsigned int are
>>> necessary - as it is possible to cast between long and int, but feel
>>> free to correct me.

>>> In WASM, the specification for those methods can be found here:

>>> [ https://www.w3.org/TR/wasm-core-1/#op-trunc-u |
>>> https://www.w3.org/TR/wasm-core-1/#op-trunc-u ]
>>> [ https://www.w3.org/TR/wasm-core-1/#op-convert-u |
>>> https://www.w3.org/TR/wasm-core-1/#op-convert-u ]

>>> Note that the WASM specification is undefined for some values, notably
>>> NaN, infinities, and values that fall out of the range.

>>> As *I* want to use it to implement WASM instructions, I do not have any
>>> strong opinion on the undefined cases - for example, returning the
>>> nearest unsigned long value or throwing an exception is fine for me.

>>> What do you think?

>>> - Johannes

>> --
>> - DML • he/him

> --
> - DML • he/him
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20221111/acd07367/attachment-0001.htm>


More information about the core-libs-dev mailing list