Page 2 of 2
Posted: Fri Dec 29, 2006 6:33 pm
by remi_meier
Is it more accurate than the normal FPU rounding?
Code: Select all
Structure s_Round
StructureUnion
;
i.q
u.q
f.d
;
EndStructureUnion
EndStructure
Procedure.l Round2(Value.d)
;
Protected temp.s_Round
;
temp\f = Value + 6755399441055744.0
;
ProcedureReturn temp\u
;
EndProcedure
Procedure.l Round3(Value.d)
ProcedureReturn Value
EndProcedure
Debug Round2(328569072.31)
Debug Round2(328569072.51)
Debug Round3(328569072.31)
Debug Round3(328569072.51)
what about negative numbers?
Posted: Tue Jan 02, 2007 6:35 am
by citystate
Your procedure seems to work fine for positive numbers, but FLOOR should calculate negative numbers differently. Seeing that the function of FLOOR is to round
down, a negative number should round down to the number with a larger absolute value. That is FLOOR( -7.8 ) should equal -8 not -7.
Code: Select all
floor = INT(number*POW(10,precision))/POW(10,precision)
does the same thing as your proposed FLOOR procedure
Re: Floor()
Posted: Mon Jan 30, 2017 1:08 am
by jack
I know it's an old thread but why make a new thread of the same subject?
for 32-bit change rax to eax
btw in the procedure PBfrac the result is not returned unless assigned to a variable
Code: Select all
ImportC ""
floor.d( doubleValue.d)
ceil.d( doubleValue.d)
trunc.d( doubleValue.d)
EndImport
Procedure.i PBfloor(x.d)
EnableASM
movsd xmm0,[p.v_x]
!roundsd xmm0, xmm0, 9
!cvttsd2si rax, xmm0
DisableASM
ProcedureReturn
EndProcedure
Procedure.i PBceil(x.d)
EnableASM
movsd xmm0,[p.v_x]
!roundsd xmm0, xmm0, 10
!cvttsd2si rax, xmm0
DisableASM
ProcedureReturn
EndProcedure
Procedure.i PBtrunc(x.d)
EnableASM
movsd xmm0,[p.v_x]
!cvttsd2si rax, xmm0
DisableASM
ProcedureReturn
EndProcedure
Procedure.d PBfrac(x.d)
frc.d
EnableASM
movsd xmm0,[p.v_x]
!cvttsd2si rax, xmm0
!cvtsi2sd xmm1,rax
!subsd xmm0,xmm1
movsd [p.v_frc],xmm0
DisableASM
ProcedureReturn frc
EndProcedure
i.i
x.d=4
y.d=0.1
Debug "PBfloor CRTfloor PBceil CRTceil PBtrunc CRTtrunc PBfrac"
For i=1 To 12
s.s="("+StrD(PBfloor(x),4)+" , "+StrD(floor(x),4)+"), ("+StrD(PBceil(x),4)+" , "+StrD(ceil(x),4)
s+"), ("+StrD(PBtrunc(x),4)+" , "+StrD(trunc(x),4)+") "+StrD(PBfrac(x),15)
Debug s
x+y
Next
x=-4
Debug "PBfloor CRTfloor PBceil CRTceil PBtrunc CRTtrunc PBfrac"
For i=1 To 12
s.s="("+StrD(PBfloor(x),4)+" , "+StrD(floor(x),4)+"), ("+StrD(PBceil(x),4)+" , "+StrD(ceil(x),4)
s+"), ("+StrD(PBtrunc(x),4)+" , "+StrD(trunc(x),4)+") "+StrD(PBfrac(x),15)
Debug s
x-y
Next
Re: Floor()
Posted: Mon Jan 30, 2017 7:10 am
by wilbert
roundsd requires SSE4.1
If you use it, it might be a good idea to check if the cpu supports it.
When SSE 4.1 isn't present, the MXCSR register could be used instead to control rounding mode.
x86 alternative for frac which uses 64 bit integer instead of 32.
Code: Select all
Procedure.d frac(x.d)
!fld qword [p.v_x]
!fld st0
!fisttp qword [p.v_x]
!fild qword [p.v_x]
!fsubp
!fstp qword [p.v_x]
ProcedureReturn x
EndProcedure