Announcement

Collapse
No announcement yet.

MOD Math question

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • MOD Math question

    I am trying to do some day of week stuff.
    I cannot seem to understand how MOD works no matter how much I read and re-read the explanation it doesnt jive with the results I get.

    I do not see the remainder expressed as an integer. for example:
    I would expect
    2451550 Mod 7 - to give the result 428571429
    as
    2451550/7 = 350221.428571429
    the result I get is 3 !!

    Here are some more results:
    J 2451545 J/7 350220.714285714 J Mod 7 5
    J 2451546 J/7 350220.857142857 J Mod 7 6
    J 2451547 J/7 350221 J Mod 7 0
    J 2451548 J/7 350221.142857143 J Mod 7 1
    J 2451549 J/7 350221.285714286 J Mod 7 2
    J 2451550 J/7 350221.428571429 J Mod 7 3
    J 2451551 J/7 350221.571428571 J Mod 7 4
    J 2451552 J/7 350221.714285714 J Mod 7 5
    J 2451553 J/7 350221.857142857 J Mod 7 6
    J 2451554 J/7 350222 J Mod 7 0
    J 2451555 J/7 350222.142857143 J Mod 7 1
    J 2451556 J/7 350222.285714286 J Mod 7 2
    J 2451557 J/7 350222.428571429 J Mod 7 3
    J 2451558 J/7 350222.571428571 J Mod 7 4
    J 2451559 J/7 350222.714285714 J Mod 7 5
    J 2451560 J/7 350222.857142857 J Mod 7 6
    J 2451561 J/7 350223 J Mod 7 0
    J 2451562 J/7 350223.142857143 J Mod 7 1
    J 2451563 J/7 350223.285714286 J Mod 7 2
    J 2451564 J/7 350223.428571429 J Mod

    Now you might think that this is what i want, and it is except that on Feb 24 2000 it skips a day and I cant figure out why and I think I ned to understand MOD in order to figure it out.

    ------------------
    Kind Regards
    Mike

  • #2
    This is where it skips:
    Julian 2451589 Date 1000214 CalDate 02/14/2000 Day Sunday -----
    Julian 2451590 Date 1000215 CalDate 02/15/2000 Day Mon
    Julian 2451591 Date 1000216 CalDate 02/16/2000 Day Tues
    Julian 2451592 Date 1000217 CalDate 02/17/2000 Day Wed
    Julian 2451593 Date 1000218 CalDate 02/18/2000 Day Thur
    Julian 2451594 Date 1000219 CalDate 02/19/2000 Day Fri
    Julian 2451595 Date 1000220 CalDate 02/20/2000 Day Sat
    Julian 2451596 Date 1000221 CalDate 02/21/2000 Day Sunday -----
    Julian 2451597 Date 1000222 CalDate 02/22/2000 Day Mon
    Julian 2451598 Date 1000223 CalDate 02/23/2000 Day Tues
    Julian 2451599 Date 1000224 CalDate 02/24/2000 Day Wed <---------
    Julian 2451600 Date 1000225 CalDate 02/25/2000 Day Fri
    Julian 2451601 Date 1000226 CalDate 02/26/2000 Day Sat
    Julian 2451602 Date 1000227 CalDate 02/27/2000 Day Sunday -----
    Julian 2451603 Date 1000228 CalDate 02/28/2000 Day Mon
    Julian 2451604 Date 1000229 CalDate 02/29/2000 Day Tues
    Julian 2451605 Date 1000301 CalDate 03/01/2000 Day Wed
    Julian 2451606 Date 1000302 CalDate 03/02/2000 Day Thur
    Julian 2451607 Date 1000303 CalDate 03/03/2000 Day Fri
    Julian 2451608 Date 1000304 CalDate 03/04/2000 Day Sat
    Julian 2451609 Date 1000305 CalDate 03/05/2000 Day Sunday -----
    Julian 2451610 Date 1000306 CalDate 03/06/2000 Day Mon
    Julian 2451611 Date 1000307 CalDate 03/07/2000 Day Tues
    Julian 2451612 Date 1000308 CalDate 03/08/2000 Day Wed
    Julian 2451613 Date 1000309 CalDate 03/09/2000 Day Thur
    Julian 2451614 Date 1000310 CalDate 03/10/2000 Day Fri
    Julian 2451615 Date 1000311 CalDate 03/11/2000 Day Sat
    Julian 2451616 Date 1000312 CalDate 03/12/2000 Day Sunday -----

    ------------------
    Kind Regards
    Mike

    Comment


    • #3
      I guess I should post the code too - sorry ...

      '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
      'Description : Test Julian Date
      '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
      #COMPILE EXE "DateTest.exe"

      GLOBAL Jstart AS LONG, Date AS LONG, DayStr AS STRING, CalDateStr AS STRING
      GLOBAL Day AS LONG, Jul AS LONG, Julerror AS LONG, CalDate AS LONG, hFile2 AS LONG
      GLOBAL DestFile AS STRING, i AS LONG
      '************************************************************************
      ' DateToJulian - Converts MMDDYYYY (DWORD) to Julian Date (LONG)
      '************************************************************************
      FUNCTION DateToJulian( BYVAL TSDate AS LONG ) AS LONG

      LOCAL Year AS DWORD, Day AS DWORD, Month AS DWORD, Gregorian AS DWORD
      LOCAL JulYear AS LONG, JulMonth AS LONG, Adjust AS LONG, JulDate AS LONG
      Gregorian = 588829
      Year = 1900 + FIX(TSDate/10000)
      Month = FIX((TSDate - FIX(TSDate/10000)*10000)/100)
      Day = TSDate - FIX(TSDate/100)*100

      IF ( Month > 2 ) THEN
      JulYear = Year
      JulMonth = Month + 1
      ELSE
      JulYear = Year - 1
      JulMonth = Month + 13
      END IF

      JulDate = ( INT( 365.25 * JulYear ) + INT( 30.6001 * JulMonth ) + Day + 1720995 )
      IF ( Day + ( 31 * ( Month + ( 12 * Year ) ) ) ) >= Gregorian THEN
      Adjust = INT( 0.01 * JulYear )
      JulDate = ( JulDate + 2 - Adjust + INT( 0.25 * Adjust ) )
      END IF
      DateToJulian = JulDate
      END FUNCTION
      '************************************************************************
      ' JulianToDate - Converts Julian Date (LONG) to MMDDYYYY (DWORD)
      '************************************************************************
      FUNCTION JulianToDate( BYVAL JulDate AS LONG ) AS LONG

      LOCAL Year AS DWORD, Day AS DWORD, Month AS DWORD, Gregorian AS DWORD
      LOCAL JulA AS LONG, Jul_Alpha AS LONG, JulB AS LONG, JulC AS LONG', TSDate AS LONG
      LOCAL JulD AS LONG, JulE AS LONG, CalDate AS DWORD
      Gregorian = 2299161
      IF ( JulDate >= Gregorian ) THEN
      Jul_Alpha = INT( ( ( JulDate - 1867216 ) - 0.25 ) / 36524.25 )
      JulA = ( JulDate + 1 + Jul_Alpha - INT( 0.25 * Jul_Alpha ) )
      ELSE
      JulA = JulDate
      END IF

      JulB = JulA + 1524
      JulC = INT( 6680! + ( ( JulB - 2439870 ) - 122.1 ) / 365.25 )
      JulD = INT( 0.25 * JulC ) + ( 365 * JulC )
      JulE = INT( ( JulB - JulD ) / 30.6001 )

      Day = JulB - JulD - INT( 30.6001 * JulE )
      Month = JulE - 1
      IF ( Month > 12 ) THEN Month = Month - 12
      Year = JulC - 4715
      IF ( Month > 2 ) THEN Year = Year - 1

      JulianToDate = CLNG( (Year-1900)*10000 + Month*100 + Day )
      END FUNCTION
      '************************************************************************
      ' JulianToDate - Converts TradeStation Date (LONG) to Day of Week (LONG)
      '************************************************************************
      FUNCTION DayOfWeek( BYVAL TDate AS LONG ) AS LONG
      LOCAL TSDateJul AS LONG
      TSDateJul = DateToJulian(TDate)
      DayOfWeek = TSDateJul MOD 7
      END FUNCTION
      '************************************************************************
      ' DateToJulian - Converts TSdate (Y)YYMMDD to Calendar Date (LONG)
      '************************************************************************
      FUNCTION TStoCalDate( BYVAL TSDate AS LONG ) AS LONG
      TStoCalDate = 1900 + (TSDate/10000 - INT(TSDate/10000))*100000000 + INT(TSDate/10000)
      END FUNCTION
      '************************************************************************
      FUNCTION PBMAIN
      DestFile = "Dates.txt
      hFile2 = FREEFILE
      OPEN DestFile FOR OUTPUT AS hFile2 ' Create/Overwrite output file

      Jstart = DateToJulian(970101)
      FOR i = Jstart TO Jstart + 2900
      Date = JulianToDate(i)
      CalDate = TStoCalDate(Date)
      CalDateStr = TRIM$(STR$(CalDate))
      IF LEN(CalDateStr) < 8 THEN CalDateStr = "0"+CalDateStr
      CalDateStr = LEFT$(CalDateStr,2)+"/"+LEFT$(RIGHT$(CalDateStr,6),2)+"/"+RIGHT$(CalDateStr,4)
      Day = DayOfWeek(i)
      Jul = DateToJulian(Date)

      SELECT CASE Day
      CASE 0
      DayStr = "Sunday -----"
      CASE 1
      DayStr = "Mon"
      CASE 2
      DayStr = "Tues"
      CASE 3
      DayStr = "Wed"
      CASE 4
      DayStr = "Thur"
      CASE 5
      DayStr = "Fri"
      CASE 6
      DayStr = "Sat"
      END SELECT
      JulError = i - Jul
      IF JulError > 0 THEN MSGBOX("ERROR !!!!")
      PRINT# hFile2, "Julian "+STR$(i)+" Date "+STR$(Date)+" CalDate "+_
      CalDateStr+" Day "+DayStr ' Write a line

      NEXT
      CLOSE #hFile2 ' Close Output file
      MSGBOX("Finished")
      END FUNCTION
      '¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤'


      ------------------
      Kind Regards
      Mike

      Comment


      • #4
        I didn't look closely at your code, but I can help you with the concept behind MOD...

        > I would expect 2451550 Mod 7 - to give the result 428571429

        This should make it clearer...

        Code:
         0 MOD 7 = 0
         1 MOD 7 = 1
         2 MOD 7 = 2
         3 MOD 7 = 3
         4 MOD 7 = 4
         5 MOD 7 = 5
         6 MOD 7 = 6
         7 MOD 7 = 0
         8 MOD 7 = 1
         9 MOD 7 = 2
        10 MOD 7 = 3
        11 MOD 7 = 4
        12 MOD 7 = 5
        13 MOD 7 = 6
        14 MOD 7 = 0
        15 MOD 7 = 1
        16 MOD 7 = 2
        17 MOD 7 = 3
        The result of a MOD operation, when used this way, will always cycle between 0 and one less than the number you specify. So performing a MOD 7 operation will result in values from 0 to 6.

        It does not return the "fraction", it returns the "remainder". For example, 10 divided by 7 is 1, with a remainder of 3. You are apparently expecting the result to be 3/7 but the correct answer is just 3.

        That may help you figure out why your code is "skipping" days... My guess is that you are using a floating point division (/) someplace where you should be using integer division (\) or vice versa.

        -- Eric


        ------------------
        Perfect Sync Development Tools
        Perfect Sync Web Site
        Contact Us: mailto:[email protected][email protected]</A>



        [This message has been edited by Eric Pearson (edited March 10, 2001).]
        "Not my circus, not my monkeys."

        Comment


        • #5
          Eric,
          Could you DEFINE remainder please.
          It seems to me that the remainder IS a fraction ie less than 1, and that the remainder of 5/7 is not 5 but .714285......
          Expressed as an integer would be 714285....
          So I would expect 5 MOD 7 to be at least 7 not 5.
          So i suspect MOD performs a second calculation after determining the fractional portion, and that is a division and a rounding to express the result as ONE number between 0 and 7.

          This is fine (I wish the manual would say so) but I dont see why I get an unpredictable result around Feb24

          ------------------
          Kind Regards
          Mike

          Comment


          • #6
            "Remainder" is "what's left over after a division". It's even more basic that a "fraction".

            MOD is not really defined by PowerBASIC, it a basic arithmetic operation along the lines of addition, subtraction, etc. It has a precise mathematical meaning.

            Let's say you divide 12 by 7 and get 1, with 5 left over. That represents 5/7, right? Would you expect the number that MOD returned to be 7, or 71, or 714, or 7142...?

            MOD is almost always paired with integer division.

            -- Eric

            ------------------
            Perfect Sync Development Tools
            Perfect Sync Web Site
            Contact Us: mailto:[email protected][email protected]</A>
            "Not my circus, not my monkeys."

            Comment


            • #7
              Remainder is defined as the difference between the dividend and the
              product of the divisor and quotient.5 mod 7 is indeed 5.
              cheers and beers!

              ------------------

              Comment


              • #8
                Here's a more pertinent example. Let's say the first day of the month is a Monday (day 1)...

                Code:
                Day Of Month  Day Of Week
                ------------  -----------
                     1   MOD 7 =  1
                     2            2
                     3            3
                     4            4
                     5            5
                     6            6
                     7            0
                     8            1
                     9            2
                    10            3
                    11            4
                    12            5
                    13            6
                    14            0
                    15            1
                    16            2
                    17            3
                    18            4
                    19            5
                    20            6
                etc...
                Of course, that only works if the first is a Monday. But think about Julian Dates, which are sequential numbers that assigned to dates. If you "sync" it properly, i.e. if you know the Day Of Week of the first Julian Date, you can use MOD to get the Day Of Week of any Julian Date.

                See how useful it is?

                -- Eric





                ------------------
                Perfect Sync Development Tools
                Perfect Sync Web Site
                Contact Us: mailto:[email protected][email protected]</A>



                [This message has been edited by Eric Pearson (edited March 10, 2001).]
                "Not my circus, not my monkeys."

                Comment


                • #9
                  One more quick thought... If you have 10 widgets and you divide them among 3 people, each person gets 3, and you have 1 widget left over, not 1/3 of a widget.

                  The remainder is 1.

                  -- Eric

                  ------------------
                  Perfect Sync Development Tools
                  Perfect Sync Web Site
                  Contact Us: mailto:[email protected][email protected]</A>
                  "Not my circus, not my monkeys."

                  Comment


                  • #10
                    A) 12 \ 7 = 1
                    B) 12 MOD 7 = 5

                    Code:
                           1  '=A
                        ----
                      7 | 12
                          -7
                          --
                           5  '=B


                    ------------------
                    Bernard Ertl
                    Bernard Ertl
                    InterPlan Systems

                    Comment


                    • #11
                      Mike
                      Here is day of the week function taken from my Julian routines.
                      Code:
                      '=============================================================================
                      '  FUNCTION DayOfWeek(BYVAL jdn AS LONG) AS LONG
                      '
                      '  Convert a JDN to a day-of-week number (0 to 6).  Where 0 stands for
                      '  Sunday, 1 for Monday, etc. and 6 stands for Saturday.
                      '=============================================================================
                      FUNCTION DayOfWeek(BYVAL Jdn AS LONG) AS LONG
                      
                      DIM dow AS LOCAL LONG
                      
                      dow = (Jdn + 1) MOD 7
                      IF (dow >= 0) THEN
                         FUNCTION = dow
                      ELSE
                         FUNCTION = dow + 7
                      END IF
                      
                      END FUNCTION
                      ------------------

                      Comment


                      • #12
                        Ahhhh ok I get it.

                        Thx Eric and everyone.

                        So I need to repost my Day of week problem then cos that should be working!

                        ------------------
                        Kind Regards
                        Mike

                        Comment

                        Working...
                        X