## n-fix(n)

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

### n-fix(n)

'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 DoubleDim As Double nDim As Integer mn=54.321m=10Print mymod(n,m)SleepEnd'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 solutionFunction 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 SelectEnd Function`
dafhi
Posts: 1241
Joined: Jun 04, 2005 9:51

### Re: n-fix(n)

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

### Re: n-fix(n)

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

### Re: n-fix(n)

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: 1802
Joined: Jan 02, 2017 0:34
Location: UK

### Re: n-fix(n)

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: 535
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

### Re: n-fix(n)

@ 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: 1802
Joined: Jan 02, 2017 0:34
Location: UK

### Re: n-fix(n)

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: 1241
Joined: Jun 04, 2005 9:51

### Re: n-fix(n)

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)

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: 1802
Joined: Jan 02, 2017 0:34
Location: UK

### Re: n-fix(n)

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

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

### Re: n-fix(n)

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 partEnd 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)

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)

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: 1802
Joined: Jan 02, 2017 0:34
Location: UK

### Re: n-fix(n)

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^DecPlacesEnd FunctionDim As Double nDim As Integer mDim DecPlaces As Ubyten = 54.321m = 10DecPlaces = 3Print mymod( n, m, 3 )n = 85.987654321m = 10DecPlaces = 4Print 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: 535
Joined: Apr 19, 2006 10:55
Location: Kissimmee, FL
Contact:

### Re: n-fix(n)

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.