Announcement

Collapse
No announcement yet.

Ascii value of each digit of a long?

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

  • Ascii value of each digit of a long?

    How do you get the ascii value of each digit of a long?
    Trying to get the values without using the string handling routines.
    Code:
    #COMPILE EXE
    #DIM ALL
    DECLARE FUNCTION ShowDate(month AS LONG, day AS LONG, year AS LONG) AS STRING
    FUNCTION PBMAIN AS LONG
      LOCAL month, day, year AS LONG
      DIM s AS STRING
      s = "00/00/0000"
      month = 11
      day   = 12
      year  = 9473
      ? ShowDate(month, day, year)
      WAITKEY$
    END FUNCTION
     
    FUNCTION ShowDate (month AS LONG, day AS LONG, year AS LONG) AS STRING
      LOCAL s AS STRING
      s         = "00/00/0000"
      ASC(s,1)  = month \10  +48
      ASC(s,2)  = month MOD 10 + 48
      ASC(s,4)  = day\10 + 48
      ASC(s,5)  = day MOD 10 + 48
     
      ASC(s,7)  = year\1000 +48
      'ASc(s,8)  =
      'asc(s,9)  =
      'asc(s,10) =
      FUNCTION = s
    END FUNCTION
    Last edited by Mike Doty; 19 Apr 2008, 02:40 PM.
    How long is an idea?

  • #2
    Code:
    FUNCTION PBMAIN () AS LONG
    
    InitialValue&=1234567890
        
    Remains&=InitialValue&
    FOR digit& = 1 TO 10
        NextDigit&=Remains& MOD 10
        Remains&=Remains& \ 10
        NextCharacter&=NextDigit& + 48
        
        PRINT NextDigit& , NextCharacter&, CHR$(NextCharacter&)
    NEXT
    
    WAITKEY$
                        
    END FUNCTION

    Comment


    • #3
      Nice! Thank you.

      Code:
      #COMPILE EXE
      #DIM ALL
      DECLARE FUNCTION ShowDate(month AS LONG, day AS LONG, year AS LONG) AS STRING
      FUNCTION PBMAIN AS LONG
        LOCAL month, day, year AS LONG
        DIM s AS STRING
        s = "00/00/0000"
        month = 12
        day   = 1
        year  = 1989
        ? ShowDate(month, day, year)
        WAITKEY$
      END FUNCTION
       
      FUNCTION ShowDate (month AS LONG, day AS LONG, year AS LONG) AS STRING
        LOCAL s AS STRING
        LOCAL remains AS LONG
        LOCAL digit AS LONG
        LOCAL nextdigit AS LONG
        LOCAL nextcharacter AS LONG
        s         = "00/00/0000"
        ASC(s,1)  = month \10  +48
        ASC(s,2)  = month MOD 10 + 48
        ASC(s,4)  = day\10 + 48
        ASC(s,5)  = day MOD 10 + 48
        Remains&=year
        FOR digit& = 10 TO 7 STEP -1    'changed from 4 to 1 to 10 to 7
          NextDigit&=Remains& MOD 10
          Remains&=Remains& \ 10
          NextCharacter&=NextDigit& + 48
          ASC(s,digit) = NextCharacter   'no longer need to add 6
        NEXT
        FUNCTION = s
      END FUNCTION
      Last edited by Mike Doty; 19 Apr 2008, 10:55 PM.
      How long is an idea?

      Comment


      • #4
        Hey Mike,
        2 more...

        Code:
          
        #COMPILE EXE '#CC 4.04#
        #DIM ALL
        '______________________________________________________________________________
         
        FUNCTION ShowDateA(BYVAL Month AS LONG, BYVAL Day AS LONG, BYVAL Year AS LONG) AS STRING
         LOCAL sString AS STRING * 10
         LOCAL pChar   AS BYTE POINTER
         LOCAL Looper  AS LONG
         
         pChar = VARPTR(sString) + 9
         FOR Looper = 1 TO 10
           SELECT CASE Looper
             CASE 1 TO 4 : @pChar = (Year MOD 10) + 48  : Year = Year \ 10
             CASE 5, 8   : @pChar = 47
             CASE 6, 7   : @pChar = (Day MOD 10) + 48   : Day = Day \ 10
             CASE 9, 10  : @pChar = (Month MOD 10) + 48 : Month = Month \ 10
           END SELECT
           DECR pChar
         NEXT
         
         FUNCTION = sString
         
        END FUNCTION
        '______________________________________________________________________________
         
        FUNCTION ShowDateB(BYVAL Month AS LONG, BYVAL Day AS LONG, BYVAL Year AS LONG) AS STRING
         LOCAL sString AS STRING * 10
         LOCAL pChar   AS BYTE POINTER
         
         pChar = VARPTR(sString)
         
         @pChar[9] = (Year MOD 10) + 48  : Year = Year \ 10
         @pChar[8] = (Year MOD 10) + 48  : Year = Year \ 10
         @pChar[7] = (Year MOD 10) + 48  : Year = Year \ 10
         @pChar[6] = (Year MOD 10) + 48  
         @pChar[5] = 47
         @pChar[4] = (Day MOD 10) + 48   : Day = Day \ 10
         @pChar[3] = (Day MOD 10) + 48
         @pChar[2] = 47
         @pChar[1] = (Month MOD 10) + 48 : Month = Month \ 10
         @pChar[0] = (Month MOD 10) + 48
         
         FUNCTION = sString
         
        END FUNCTION
        '______________________________________________________________________________
         
        FUNCTION PBMAIN AS LONG
         LOCAL Month AS LONG
         LOCAL Day   AS LONG
         LOCAL Year  AS LONG
         
         Month =   12
         Day   =   01
         Year  = 1989
         
         PRINT ShowDateA(Month, Day, Year)
         PRINT ShowDateB(Month, Day, Year)
         
         PRINT : PRINT "Press any key or click to continue..." : MOUSE ON : MOUSE 3, UP : WAITKEY$
         
        END FUNCTION
        '______________________________________________________________________________
        '
         
         
        Last edited by Pierre Bellisle; 20 Apr 2008, 09:06 PM.

        Comment


        • #5
          FWIW, this problem is called the "decimal print" routine and for a long time was the subject of many "mine's smaller than yours" contests. (Measurements taken in 'instructions')

          You might try a search on "decimal print" if you want more ideas.

          Also FWIW, here are the 'hex-binary' versions of this (going both ways). You could tinker with that some to do decimal. Well, Ok, you'd have a tinker a lot. http://www.powerbasic.com/support/pb...ad.php?t=25176
          Last edited by Michael Mattias; 20 Apr 2008, 12:39 PM.
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            There are 26 letters in our alphabet. The nearest binary count value would be 32 (00000b to 111111b). To represent five letters consecutively in a single numeric value, you would need a total of 25 bits. Even six characters can be squeezed into 30 bits, and we can easily represent integers of 32 bits.

            Arranging the bits so that no two words create an identical total is easy. Say that your word is placed in a string called AB$. Then you can create a unique total using (ASC(ab$,1)-65)*32^5+(ASC(ab$,2)-65)*32^4+(ASC(ab$,3)-65)*32^3+(ASC(ab$,4)-65)*32^2+(ASC(ab$,5)-65)*32^1

            This could also be done using a FOR loop:

            b=0
            FOR a=1 to LEN(ab$)
            b=b*32+ASC(ab$,a)-65
            NEXT

            Because 6 combinations in the possibilities of a 2^5 (or 32 count) bit representation are unused, you may find some unique uses for these as well.
            But to exhaust all the possibilities of character combinations from AAAAA to ZZZZZ would mean 11,881,376 spelling possibilities, of which only a comparatively few would be valid. Yet with 30 bits of encoding, (five bits for each character), we have a grand total of 33,554,432 possibilities for our range, again with only a comparatively small number representing valid words. So constructing a table with either value as an index would be very wasteful of memory or disk storage.

            There are ways you can reduce this amount. Since each index could point to an individual byte, and each byte is composed of 8 bits, you could set a bit if a certain spelling is valid and leave it clear if it were invalid or if the combination is not used. Then you could take the 33,554,432 and divide it by 8 to point at the right byte, then use the remainder (using the MOD operator) to select the specific bit and test to see it if is valid or not. That would reduce the index range to an effective 4,194,304 reference to bytes of memory.

            However, we can go smaller. Instead of five bits, we can just use the 26 character possibilities and rewrite our expression this way:

            (ASC(ab$,1)-65)*26^5+(ASC(ab$,2)-65)*26^4+(ASC(ab$,3)-65)*26^3+(ASC(ab$,4)-65)*26^2+(ASC(ab$,5)-65)*26^1

            Or, using our FOR loop approach:

            b=0
            FOR a=1 to LEN(ab$)
            b=b*26+ASC(ab$,a)-65
            NEXT

            Now we are down to using the 11,881,376 possibilities that are actually required. Again, using the byte reference method described next, we can reduce this value to 1,485,172 byte references, then use the MOD of the actual count to find which bit to query for a valid word.

            If that number is unacceptable, you can attempt a study of the written word and see if you can find any hard and fast rules about what letter combinations never occur together. For instance, "qz" might be suspect, or "vb". Maybe you can work on minimizing the two-letter combinations from AA to ZZ, which is 26^2, to something much smaller.

            Or, you can consider a hashing approach. In a hashing approach, you try to reduce the total to something much smaller, but accept that some combinations will be duplicates. For instance, you could remove the vowels from consideration, and just encode the remaining letters. The vowels are A, E, I, O, and U, and the remaining letter represent only 21 possibilities. Including Y as a vowel could reduce this to 20 possibilities. Since every word has to have at least one vowel, you could see that five letters can be reduced to four or less if you do this. This means that the word "SOAR" now becomes "SR", which might also match "SIRE" or "SURE". These collisions are where the art of hashing comes in, because you must point the way to where each can be validated via a secondary method.

            So while you may have found a place where hashing can be used beneficially, you also are at a place where you have to figure out how to implement it. Hashing is an approach to reducing the scale of a data reference, not a technique or method that works the same way in all circumstances.

            I should mention that for the purpose of this discussion, I am assuming that all characters are upper case. If not, you need to force them to upper case, or you will end up with 52 character values instead of just 26.

            Comment


            • #7
              Let Microsoft worry about it?
              Code:
              #INCLUDE "win32api.inc"
              FUNCTION ShowDate (month AS LONG, day AS LONG, year AS LONG) AS STRING
              
                LOCAL st As SYSTEMTIME, szDF AS ASCIIZ * 48, szDate As ASCIIZ * 48 
              
                   st.wYear  = year
                   st.wMonth = month
                   st.wDay   = day 
                   szDf      = "MM'/'dd'/'yyyy"    ' for MM/DD/CCYY
               
                   GetDateFormat    BYVAL %NULL, BYVAL %NULL ,st, szDf, szDate, SIZEOF (szDate)
                   FUNCTION      = szDate
                
              END FUNCTION
              Michael Mattias
              Tal Systems (retired)
              Port Washington WI USA
              [email protected]
              http://www.talsystems.com

              Comment

              Working...
              X