Re: converting an unsigned 64 bit in a FPU double
- From: Phil Carmody <thefatphil_demunged@xxxxxxxxxxx>
- Date: 21 Nov 2007 14:20:16 +0200
Terje Mathisen <spamtrap@xxxxxxxxxx> writes:
Phil Carmody wrote:
jacob navia <spamtrap@xxxxxxxxxx> writes:
HiFor most questions like this, about tiny and common primitives, the
Suppose following:
You got in some general 64 bit reg (say rax) an unsigned
number and you want to convert it to long double
(FPU 80 bits)
answer is simply to see how gcc does it, and do that.
The best I thought can be done is:That expects to load a floating point value. You don't have a
(using gcc notation)
push $0
push rax
fldq (%rsp)
floating point value.
To load a _signed_ integer you use the FILD* instructions
If your unsigned value is larger than 63 bits, then you'll
need to fix up (by subtracting 2^64).
Yeah, unsigned 64-bit is somewhat troublesome. :-(
I used to use uint64_t for a lot of my prime number work,
working modulo small primes. Annoyances everywhere.
Eventually realised that balanced representation wasn't
just more efficient from a Int<->FPU perspective (of which
there was plenty), but had several other benefits,
including _increased_ ranges of numbers that I could work
with, sometimes. int64_t almost everywhere now.
The easiest (and by far most portable!) way I've found is to simply
bias the input, then adjust the result, i.e.:
extended uint64_to_extended(uint64_t u64)
{
u64 -= ((uint64_t) 1) << 63; // Bias the input
You don't need the carry, so you can just toggle the
63rd bit as a logical operation rather than an arithmetic
one.
extended e = (extended) ((int64_t) u64); // Convert to fp
e += 32768.0*65536.0*65536.0*65536.0; // Un-bias the result
return e;
}
If, otoh, maximally large input values are quite rare, then it will be
much faster to use a test/branch to handle those values:
extended uint64_to_extended(uint64_t u64)
{
int64_t i64 = (int64_t) u64;
extended e = (extended) i64; // Convert to fp
// Check if the input was >= 2^63
if (i64 < 0) { // Top/Sign bit set?
e += 65536.0*65536.0*65536.0*65536.0;
}
return e;
}
For reference, GCC (4.2) compiles that into _exactly_
the same code as
extended uint64_to_extended(uint64_t u64) { return(extended)u64; }
Phil
--
Dear aunt, let's set so double the killer delete select all.
-- Microsoft voice recognition live demonstration
.
- Follow-Ups:
- Re: converting an unsigned 64 bit in a FPU double
- From: Terje Mathisen
- Re: converting an unsigned 64 bit in a FPU double
- References:
- converting an unsigned 64 bit in a FPU double
- From: jacob navia
- Re: converting an unsigned 64 bit in a FPU double
- From: Phil Carmody
- Re: converting an unsigned 64 bit in a FPU double
- From: Terje Mathisen
- converting an unsigned 64 bit in a FPU double
- Prev by Date: Nasm, macho and Macos problem
- Next by Date: Re: Nasm, macho and Macos problem
- Previous by thread: Re: converting an unsigned 64 bit in a FPU double
- Next by thread: Re: converting an unsigned 64 bit in a FPU double
- Index(es):
Relevant Pages
|
|