mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 08:06:06 +02:00
* softfpu.pp: reverted r28318 and replaced it with a improved solution:
* Moved handling of 64-bit values > high(int64) to qword_to_float64, so that normalizeRoundAndPackFloat64 procedure stays unmodified compared to C source. * Using "jamming" right shift instead of regular one, so the least significant bit is not dropped but participates in rounding. * Take a shortcut for values with <= 53 significant bits, which are convertible into float64 exactly and do not need rounding. git-svn-id: trunk@28346 -
This commit is contained in:
parent
cb470da8d9
commit
ee8fcc8bdb
@ -2868,8 +2868,6 @@ point value corresponding to the abstract input. This routine is just like
|
|||||||
`roundAndPackFloat64' except that `zSig' does not have to be normalized.
|
`roundAndPackFloat64' except that `zSig' does not have to be normalized.
|
||||||
Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
|
Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
|
||||||
floating-point exponent.
|
floating-point exponent.
|
||||||
--
|
|
||||||
additionally the Pascal version should support Bit 63 set in 'zSig'
|
|
||||||
----------------------------------------------------------------------------
|
----------------------------------------------------------------------------
|
||||||
*}
|
*}
|
||||||
|
|
||||||
@ -2878,10 +2876,7 @@ function normalizeRoundAndPackFloat64(zSign: flag; zExp: int16; zSig: bits64): f
|
|||||||
shiftCount: int8;
|
shiftCount: int8;
|
||||||
begin
|
begin
|
||||||
shiftCount := countLeadingZeros64( zSig ) - 1;
|
shiftCount := countLeadingZeros64( zSig ) - 1;
|
||||||
if ( shiftCount <= 0) then
|
result := roundAndPackFloat64( zSign, zExp - shiftCount, zSig shl shiftCount);
|
||||||
result := roundAndPackFloat64( zSign, zExp - shiftCount, zSig shr (-shiftCount))
|
|
||||||
else
|
|
||||||
result := roundAndPackFloat64( zSign, zExp - shiftCount, zSig shl shiftCount);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{*
|
{*
|
||||||
@ -5832,11 +5827,26 @@ End;
|
|||||||
*----------------------------------------------------------------------------*}
|
*----------------------------------------------------------------------------*}
|
||||||
function qword_to_float64( a: qword ): float64;
|
function qword_to_float64( a: qword ): float64;
|
||||||
{$ifdef fpc}[public,Alias:'QWORD_TO_FLOAT64'];compilerproc;{$endif}
|
{$ifdef fpc}[public,Alias:'QWORD_TO_FLOAT64'];compilerproc;{$endif}
|
||||||
|
var
|
||||||
|
shiftCount: int8;
|
||||||
Begin
|
Begin
|
||||||
if ( a = 0 ) then
|
if ( a = 0 ) then
|
||||||
result := packFloat64( 0, 0, 0 )
|
result := packFloat64( 0, 0, 0 )
|
||||||
else
|
else
|
||||||
result := normalizeRoundAndPackFloat64( 0, $43c, a );
|
begin
|
||||||
|
shiftCount := countLeadingZeros64(a) - 1;
|
||||||
|
{ numbers with <= 53 significant bits are converted exactly }
|
||||||
|
if (shiftCount > 9) then
|
||||||
|
result := packFloat64(0, $43c - shiftCount, a shl (shiftCount-10))
|
||||||
|
else if (shiftCount>=0) then
|
||||||
|
result := roundAndPackFloat64( 0, $43c - shiftCount, a shl shiftCount)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{ the only possible negative value is -1, in case bit 63 of 'a' is set }
|
||||||
|
shift64RightJamming(a, 1, a);
|
||||||
|
result := roundAndPackFloat64(0, $43d, a);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user