Results 1 to 8 of 8

Thread: MOD operator problems

  1. #1

    Thread Starter
    New Member
    Join Date
    Jul 2018
    Posts
    7

    MOD operator problems

    Hi, All,
    I'm intermediate for VB6. I want to get remainder from divided two doubles. I used ,

    Dim a As Double, b As Double, result As Double
    b = 8333.33
    a = 58333.31

    result = a - (b * Fix(a / b))

    result is 8333.33; Why? Please help.

  2. #2
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,734

    Re: MOD operator problems

    Code:
    a=58333,31    b=8333,33
    Fix(a / b) ->  6 
    b * 6 ->  49999,98 
    a - (49999,98) ->  8333,33
    What's your actual question?

  3. #3
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,734

    Re: MOD operator problems

    https://stackoverflow.com/questions/...dulo-operation
    Code:
    The algorithm you want, to limit a floating point value between 0 and some modulus n:
    
    Double fmod(Double value, Double modulus)
    {
        return value - Trunc(value/modulus)*modulus;
    }
    for example pi mod e (3.14159265358979 mod 2.718281828459045)
    
    3.14159265358979 / 2.718281828459045 
       = 1.1557273497909217179
    
    Trunc(1.1557273497909217179)
       = 1
    
    1.1557273497909217179 - 1
       = 0.1557273497909217179
    
    0.1557273497909217179 * e
       = 0.1557273497909217179 * 2.718281828459045
       = 0.42331082513074800
    pi mod e = 0.42331082513074800
    VB6:
    Code:
    Private Sub Form_Load()
      Dim a As Double, b As Double, result As Double
    
      b = 8333.33
      a = 58333.31
    
      result = a - (b * Fix(a / b))
      Debug.Print result
      Debug.Print fmod(a, b)
    
      Debug.Print fmod(3.14159265358979, 2.71828182845905)
      ' -> 0.423310825130745
    End Sub
    
    Private Function fmod(value As Double, modulus As Double) As Double
        fmod = value - Fix(value / modulus) * modulus
    End Function

  4. #4

    Thread Starter
    New Member
    Join Date
    Jul 2018
    Posts
    7

    Re: MOD operator problems

    b = 8333.33
    a = 58333.31

    a/b =7 and no remain. So Fix(a / b) should be 7. But Fix(a / b)=6, is it correct?
    Last edited by plaahemantha; Apr 7th, 2021 at 05:04 AM.

  5. #5
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,734

    Re: MOD operator problems

    That's the problem with floating point number respresentation, calculation and the internal storage in 64 bits.
    Code:
    ? 7 * 8333.33 - 58333.31
     1.81898940354586E-12

  6. #6
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: MOD operator problems

    Quote Originally Posted by Arnoutdv View Post
    That's the problem with floating point number respresentation, calculation and the internal storage in 64 bits.
    Code:
    ? 7 * 8333.33 - 58333.31
     1.81898940354586E-12
    Yep, a floatingpoint-mod-function needs to take these "small epsilons" into account:

    Code:
    Private Sub Form_Load()
      Dim a#: a = 58333.31
      Dim b#: b = 8333.33
       
      Debug.Print a - b * Fix(a / b), fmod(a, b)
    End Sub
    
    Public Function fmod(ByVal Dividend#, ByVal Divisor#) As Double
      fmod = Dividend - Fix(Dividend / Divisor) * Divisor
     
      If Abs(fmod - Divisor) < Abs(Divisor * 0.000000001) Then fmod = 0
    End Function
    HTH

    Olaf

  7. #7
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    6,167

    Re: MOD operator problems

    Or use some small EPSILON value to fix the Fix function and to implemented comparison to zero with |A| < EPSION using Abs function like this:

    Code:
    Option Explicit
    
    Private Const EPSILON As Double = 0.0000001
    
    Private Sub Form_Load()
        Dim a#: a = 58333.31
        Dim b#: b = -8333.33
      
        Debug.Print "No remainder? -> "; Abs(fmod(a, b)) < EPSILON
        Debug.Print Format$(fmod(a, b), "0.0000")
        Debug.Print Format$(fmod(a, b), "0.00000000")
        Debug.Print Format$(fmod(a, b), "0.000000000000")
    End Sub
    
    Private Function fmod(value As Double, modulus As Double) As Double
        fmod = value - Fix(value / modulus + Sgn(value) * Sgn(modulus) * EPSILON) * modulus
    End Function
    cheers,
    </wqw>

  8. #8
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: MOD operator problems

    Quote Originally Posted by wqweto View Post
    Or use some small EPSILON value to fix the Fix function and to implemented comparison to zero with |A| < EPSION using Abs function like this:

    Code:
    Option Explicit
    
    Private Const EPSILON As Double = 0.0000001
    
    Private Sub Form_Load()
        Dim a#: a = 58333.31
        Dim b#: b = -8333.33
      
        Debug.Print "No remainder? -> "; Abs(fmod(a, b)) < EPSILON
        Debug.Print Format$(fmod(a, b), "0.0000")
        Debug.Print Format$(fmod(a, b), "0.00000000")
        Debug.Print Format$(fmod(a, b), "0.000000000000")
    End Sub
    
    Private Function fmod(value As Double, modulus As Double) As Double
        fmod = value - Fix(value / modulus + Sgn(value) * Sgn(modulus) * EPSILON) * modulus
    End Function
    cheers,
    </wqw>
    Thanks for the indirect hint ...
    (regarding the fmod-function I've posted in #6, which fails to return a zero with that negative Divisor-input).

    Here's a correction:
    Code:
    Public Function fmod(ByVal Dividend#, ByVal Divisor#) As Double
      Const EPS# = 0.00000001
      If Divisor < 0 Then Divisor = -Divisor
      If Dividend > 0 Then
         fmod = Dividend - Int(Dividend / Divisor) * Divisor
         If Abs(fmod - Divisor) < Divisor * EPS Then fmod = 0
      Else
         fmod = Dividend + Int(-Dividend / Divisor) * Divisor
         If Abs(fmod + Divisor) < Divisor * EPS Then fmod = 0
      End If
    End Function
    Quite a bit longer than the first version (or yours) - but it now has less internal function-calls - and is therefore about 25% faster in native-compiled binaries... (though still about 10% slower in IDE or PCode).

    Olaf

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width