Strange behavior of Fmod operation in Float32Full
tosjduenfs
Posts: 37
I'm trying to do a modulo operation in the following:
parallax serial terminal says
LHA = -147.0883
GMST = 24.375
LongDecimal = -87.83828
RaDecimal = 83.625
The correct result should be about 212.9 but it gives me -147.0883.
Has anyone else had an issue with using the modulo operation on a negative number? Am I using it incorrectly?
Thanks,
Mike
'Calculate the Local Hour Angle: LHA = GMST + Longitude - RA where 0 <= LHA <=360 LHA := FLT.Fmod(FLT.Fsub(FLT.Fadd(GMST,LongDecimal),RaDecimal),360.0)
parallax serial terminal says
LHA = -147.0883
GMST = 24.375
LongDecimal = -87.83828
RaDecimal = 83.625
The correct result should be about 212.9 but it gives me -147.0883.
Has anyone else had an issue with using the modulo operation on a negative number? Am I using it incorrectly?
Thanks,
Mike
Comments
Standards are great. Let's see what the different languages actually do:
Python: JavaScript:
C:
C#: (Using IEEERemainer function)
bc: Arbitrary precision calculator on Linux
Turns out only Python agrees with you here.
is specified as far as I remember to the bit. The only thing that might be causing variation is the rounding mode
which affects various operations, but in a precisely determined way. I don't have a copy of the spec to hand so
can't lookup Fmod.
I just check and the OBEX version hasn't been updated with the latest bug fix. The latest version can be found in post #98 of Jonathan's thread.
I agree with you. I would have naively assumed that on modern computers such operations were passed on to a floating point unit and the language would accept whatever came back as it is, which should be IEEE 754 compliant. Or at least the languages would perform IEEE 754 in software. Seems this is not true.
So what does IEE 754 say about Floating point remainder?
So far I have found from wikipedia: "This is not like a normal modulo operation, it can be negative for two positive numbers. It returns the exact value of x(round(x/y)·y)". That sounds even worse than I would expect!
From here: http://msdn.microsoft.com/en-us/library/system.math.ieeeremainder.aspx I find that the IEEE floating point remainder is defined as:
where as modulus is defined as:
I can't even find that IEEE has a modulus operator. And the remander operator it does define may not do what you would like, for example:
Math.IEEERemainder(3, 2) = -1
Mark, I've been using the F32 object I found on the obex, I'll update to the new version to see if it give me the result I need rather than using the loops. Thanks
I just found the following note about a certain _frem function in some ARM libraries:
So there we have it.
Should Float32 do what most languages modulus operator does or it should it do what IEEE does? Should it provide both?
Have a google for fmod (as used in C) and IEEremainder. I'm sure you can even find the actual 754 specification somewhere.