Announcement

Collapse
No announcement yet.

Ascii value of each digit of a long?

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

  • Michael Mattias
    replied
    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

    Leave a comment:


  • Donald Darden
    replied
    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.

    Leave a comment:


  • Michael Mattias
    replied
    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, 11:39 AM.

    Leave a comment:


  • Pierre Bellisle
    replied
    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; 28 Apr 2021, 12:10 AM.

    Leave a comment:


  • Mike Doty
    replied
    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, 09:55 PM.

    Leave a comment:


  • Paul Dixon
    replied
    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

    Leave a comment:


  • Mike Doty
    started a topic Ascii value of each digit of a long?

    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, 01:40 PM.
Working...
X