n-fix(n)

General FreeBASIC programming questions.
owen
Posts: 503
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

n-fix(n)

Postby owen » May 22, 2017 0:19

'i wish this would work.
'Function mymod(n As Double,m As Integer) As Double
' Return Fix(n) Mod m + n - Fix(n)
'End Function

Code: Select all

Declare Function mymod(n As Double,m As Integer) As Double

Dim As Double n
Dim As Integer m

n=54.321
m=10
Print mymod(n,m)
Sleep
End

'i wish this would work
'Function mymod(n As Double,m As Integer) As Double
'   Return Fix(n) Mod m + n - Fix(n)
'End Function

'my really bad solution
Function mymod(n As Double,m As Integer) As Double
   Select Case n
      Case 0
         mymod = 0
      Case CDbl(m)
         mymod = CDbl(m)
      Case Else
         If InStr(Str(n),"e")<>0 Then
            mymod=0
         Else
            If InStr(Str(n),".")<>0 Then
               mymod=Val(Str(val(Mid(Str(n),1,InStr(Str(n),".")-1)) Mod m)+"."+Mid(Str(n),InStr(Str(n),".")+1))
            Else
               mymod = (n Mod m)
            EndIf
         End If
   End Select
End Function
dafhi
Posts: 1225
Joined: Jun 04, 2005 9:51

Re: n-fix(n)

Postby dafhi » May 22, 2017 0:50

return n - m*int(n/m)
owen
Posts: 503
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

Re: n-fix(n)

Postby owen » May 22, 2017 1:38

@ dafhi
i get
4.320999999999998
xlucas
Posts: 264
Joined: May 09, 2014 21:19
Location: Argentina

Re: n-fix(n)

Postby xlucas » May 22, 2017 1:56

Owen... why do you want a floating point function to return a modulus? The remainder of a division is an integer concept. When talking about non-integers, it's very rare to refer to the remainder or modulus. When working with integers, you have:

n \ m = Int(n / m) 'Integer division

Therefore, it makes sense to obtain the remainder as Dafhi said:

remainder = n - m * Int(n / m)

Because you first do an integer divide, which destroys the remainder data. Then you multiply again to scale the number to the same value without the remainder. Finally, you substract this from the original number. What you get is the remainder. Of course, if you do this to a floating point (real) n, your "remainder" will in general be real too, not an integer. So what you're obtaining is what I would expect.
deltarho[1859]
Posts: 1652
Joined: Jan 02, 2017 0:34
Location: UK

Re: n-fix(n)

Postby deltarho[1859] » May 22, 2017 2:15

Because n - Fix(n) => 0.320999999999998 when it should be 54.321 - 54 => 0.321

54.321 is converted to binary - cannot be done exactly. If FreeBASIC had extended precision using all of the 80 bits of the FPU then that would help but we could end up with just more '9s'.
owen
Posts: 503
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

Re: n-fix(n)

Postby owen » May 22, 2017 3:18

@ xlucas
i need the decimal portion of the mod because i use the result in calculations for my cad project such as when i rotate 364.123 i use the result of 4.123 in my dxf files (representation of the drawing)

any how mymod function works using string manipulation

just wanted to ask why fix wouldn't work
deltarho[1859]
Posts: 1652
Joined: Jan 02, 2017 0:34
Location: UK

Re: n-fix(n)

Postby deltarho[1859] » May 22, 2017 4:14

Fix is working.

The most accurate representation of 54.321 in double precision is 54.3209999999999979536369210109

"." + Mid(Str(n),InStr(Str(n),".")+1) is not using the Floating Point Unit.
dafhi
Posts: 1225
Joined: Jun 04, 2005 9:51

Re: n-fix(n)

Postby dafhi » May 22, 2017 4:16

Maybe you want the output looking nice for printing?

i use this a lot

Code: Select all

function round(in as single, places as ubyte = 2) as string
  dim as integer mul = 10 ^ places
  return str(csng(int(in * mul + .5) / mul))
End Function

? round(mymod(n, m))
thesanman112
Posts: 538
Joined: Jul 15, 2005 4:13

Re: n-fix(n)

Postby thesanman112 » May 22, 2017 15:33

Owen,

maybe the frac function is what you are looking for??? there is also a function to round to the nearest decimal specified, i just dont recall what it is.

like print using ###.####??

there is also a function called FORMAT, im just reading up on it, but it looks like it may do what you need as well.
deltarho[1859]
Posts: 1652
Joined: Jan 02, 2017 0:34
Location: UK

Re: n-fix(n)

Postby deltarho[1859] » May 22, 2017 16:41

Fix( n ) = n - Frac( n ) so n - Fix( n ) = Frac( n )

Frac(54.321) => 0.320999999999998
xlucas
Posts: 264
Joined: May 09, 2014 21:19
Location: Argentina

Re: n-fix(n)

Postby xlucas » May 22, 2017 18:18

Oh! I see then... If that is what you need, then yes, you could just manipulate the numbers manually as string or use your own data type. I think for these purposes, it could be better to represent the non integral part as a fraction instead of a mantissa. So, say you input the value 55.25. This number has a limited number of digits in decimal, but is periodic in binary. Now, if you represent it as 55 + 1/4, the base no longer matters. You could use something like this:

Code: Select all

Type Mixed
   i As Long  'Integral part
   n As UShort  'Numerator of non-integral part
   d As UShort  'Denominator of non-integral part
End Type


And build your own operators. The processing would be faster than with string manipulation, I think. Yet, unless you need to make an enormous number of calculations in a short time, you won't notice the difference.
thesanman112
Posts: 538
Joined: Jul 15, 2005 4:13

Re: n-fix(n)

Postby thesanman112 » May 22, 2017 22:11

deltarho[1859] wrote:Fix( n ) = n - Frac( n ) so n - Fix( n ) = Frac( n )

Frac(54.321) => 0.320999999999998


Dont think so.....
thesanman112
Posts: 538
Joined: Jul 15, 2005 4:13

Re: n-fix(n)

Postby thesanman112 » May 22, 2017 22:21

there are so many easy ways to fix this....
Depending on what you are going to do with results,
If its just to display the print using will do...
If it needs to recalculate then just use the format function.
deltarho[1859]
Posts: 1652
Joined: Jan 02, 2017 0:34
Location: UK

Re: n-fix(n)

Postby deltarho[1859] » May 24, 2017 1:24

Using and Format is a good way for printing purposes but here is one way to 'overcome' the truncation involved when the Floating Point Unit comes into play.

The result is rounded to a requested number of decimal places.

Code: Select all

Function mymod( n As Double, m As Integer, DecPlaces as Ubyte ) As Double
   Return Fix( n ) Mod m + Fix( Frac( n )*10^DecPlaces + 0.5)/10^DecPlaces
End Function

Dim As Double n
Dim As Integer m
Dim DecPlaces As Ubyte

n = 54.321
m = 10
DecPlaces = 3

Print mymod( n, m, 3 )

n = 85.987654321
m = 10
DecPlaces = 4

Print mymod( n, m, 4 )

Sleep

which gives

4.321
5.9877

Added: In this case I reckon that 'Int' is better than 'Fix'.
owen
Posts: 503
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

Re: n-fix(n)

Postby owen » Jun 07, 2017 15:24

deltarho[1859] that works great as long as DecPlaces does not exceed the number of DecPlaces in the number.
thanks

next question would be:
how to figure out how many DecPlaces are in the number.

Return to “General”

Who is online

Users browsing this forum: No registered users and 2 guests