1. So...what if I wanted to do something like atof?

First of all, since this is my first post to this server, let me say
this... Do you know how many years it took me to get comfortable with
C/C++? Do you know how many days it took me to get comfortable with
Euphoria?  'nough said.

Anyway, I have been working on a project using Euphoria and Win32Lib.  I
have an edit control where I want the user to enter a price.  I want to
convert and store that sequence as a floating point.  In C++ I would have
probably used atof() to do that conversion.  What is the functional
equivalent in Euphoria?

Thanks for the help in advance.

new topic     » topic index » view message » categorize

2. Re: So...what if I wanted to do something like atof?

Jonas,

Not really sure, but you might look at:

"atom_to_float64()"

Syntax: include machine.e
s = atom_to_float64(a1)

Description: Convert a Euphoria atom to a sequence of 8 single-byte values.
These 8 bytes contain the representation of an IEEE floating-point number in
64-bit format.
Comments: All Euphoria atoms have values which can be represented as 64-bit
IEEE floating-point numbers, so you can convert any atom to 64-bit format
without losing any precision.
Integer values will also be converted to 64-bit floating-point format.

Example:
 fn = open("numbers.dat", "wb")
puts(fn, atom_to_float64(157.82)) -- write 8 bytes to a file

Dan Moyer


----- Original Message -----
From: "Jonas" <jktemple at USMO.COM>
To: <EUPHORIA at LISTSERV.MUOHIO.EDU>
Sent: Monday, December 11, 2000 7:08 PM
Subject: So...what if I wanted to do something like atof?


> First of all, since this is my first post to this server, let me say
> this... Do you know how many years it took me to get comfortable with
> C/C++? Do you know how many days it took me to get comfortable with
> Euphoria?  'nough said.
>
> Anyway, I have been working on a project using Euphoria and Win32Lib.  I
> have an edit control where I want the user to enter a price.  I want to
> convert and store that sequence as a floating point.  In C++ I would have
> probably used atof() to do that conversion.  What is the functional
> equivalent in Euphoria?
>
> Thanks for the help in advance.

new topic     » goto parent     » topic index » view message » categorize

3. Re: So...what if I wanted to do something like atof?

Try useing Value() to get the string conversion
sequence entered_num
entered_num = "1.2345" -- example

atom a
a = value(entered_num)
s = atom_to_float32(a)

That is if I'm right.
euman at bellsouth.net

BTW, Jiri said (past tense) RTFM.

----- Original Message -----
From: Jonas <jktemple at USMO.COM>
To: <EUPHORIA at LISTSERV.MUOHIO.EDU>
Sent: Monday, December 11, 2000 10:08 PM
Subject: So...what if I wanted to do something like atof?


> First of all, since this is my first post to this server, let me say
> this... Do you know how many years it took me to get comfortable with
> C/C++? Do you know how many days it took me to get comfortable with
> Euphoria?  'nough said.
>
> Anyway, I have been working on a project using Euphoria and Win32Lib.  I
> have an edit control where I want the user to enter a price.  I want to
> convert and store that sequence as a floating point.  In C++ I would have
> probably used atof() to do that conversion.  What is the functional
> equivalent in Euphoria?
>
> Thanks for the help in advance.
>

new topic     » goto parent     » topic index » view message » categorize

4. Re: So...what if I wanted to do something like atof?

On Mon, 11 Dec 2000, Jonas wrote:
>> Anyway, I have been working on a project using Euphoria and Win32Lib.  I
>> have an edit control where I want the user to enter a price.  I want to
>> convert and store that sequence as a floating point.  In C++ I would have
>> probably used atof() to do that conversion.  What is the functional
>> equivalent in Euphoria?
 
You are prolly looking for the routines float32_to_atom and float64_to_atom,
both of which are described in library.doc. These routines both take a sequence
of 4/8 bit representations of a float and return an atom. but im not sure if
this is what you are looking for. 

>> Thanks for the help in advance.

You better wait with that until someone who really knows what they are talking
about answers your question :)

-- 
evil, corruption and bad taste
^[cense]

new topic     » goto parent     » topic index » view message » categorize

5. Re: So...what if I wanted to do something like atof?

>
>Anyway, I have been working on a project using Euphoria and Win32Lib.  I
>have an edit control where I want the user to enter a price.  I want to
>convert and store that sequence as a floating point.  In C++ I would have
>probably used atof() to do that conversion.  What is the functional
>equivalent in Euphoria?
>
>Thanks for the help in advance.

I don't know anything of C, but if you want to get a number value from a
string sequence use value(). I think win32lib has a getNumber routine for
getting number values from a edit control, but I'm not sure. Use
atom_to_float32 or atom_to_float64 to convert it to the machine
representation of these.
I hope this has been helpful, if not other people have written replies to
your message. Otherwise, you better find someone who really knows what
they're talking about

_____________________________________________________________________________________
Get more from the Web.  FREE MSN Explorer download : http://explorer.msn.com

new topic     » goto parent     » topic index » view message » categorize

6. Re: So...what if I wanted to do something like atof?

Hi Jonas,

>Anyway, I have been working on a project using Euphoria and Win32Lib.  I
>have an edit control where I want the user to enter a price.  I want to
>convert and store that sequence as a floating point.  In C++ I would have
>probably used atof() to do that conversion.  What is the functional
>equivalent in Euphoria?

Of course when you use getText() to retrieve whatever the user entered, you
get a Euphoria sequence returned. This can be thought of a "string" field.
But what you need in your program is to treat the user data as a monetary
amount. Both integer and floating point numbers can be stored in a Euphoria
atom. So the problem is "how to convert a sequence to an atom".

Euphoria provides a very simplistic function, value(), which can do this for
you. However, it has limitations that make it unusable in real-world
applications. For example, it stops conversion when it finds a non-digit but
still reports success. So if the user enters "12o.99" it will successfully
return the value of 12 rather than generate an error.

A number of people on the list have already created another version of
value(), including myself, which handles a larger range of possible user
input. Below is some code of mine that you can use as you see fit.

-----------------------
constant TRUE = (1=1), FALSE = (0=1)

integer vBase, vPeriod, vComma, vMoney
sequence vLegalChars
vBase = 10
vPeriod = '.'
vComma = ','
vMoney = '$'
vLegalChars = "0123456789abcdef-+.,"

----------------------------------------------------------------------------
---
-- Sets the default number base to be used when converting strings to
numbers.
global function setnumberbase(integer pNewBase)
    integer lOldBase

    lOldBase = vBase

    if pNewBase > 1 and pNewBase <= 16 then
        vBase = pNewBase
    end if

    return lOldBase
end function

----------------------------------------------------------------------------
---
-- Sets the default punctuation characters.
-- If any parameter is zero, then the corresponding punctuation symbol is
not changed.
-- All three punctuation symbols must be different from each other.
-- Returns a sequence of three elements containing the current punctuation
chars.
--   1) The 'decimal place' character. Initially '.'
--   2) The digit separator character. Initially ','
--   3) The money symbol. Initially '$'
global function setnumberpunct(integer pPeriod, integer pComma, integer
pMoney)
    sequence lOldValues

    lOldValues = {vPeriod, vComma, vMoney}

    if pPeriod >= 0 and pPeriod <= 255 then
        vPeriod = pPeriod
    end if

    if pComma >= 0 and pComma <= 255 then
        vComma = pComma
    end if

    if pMoney >= 0 and pMoney <= 255 then
        vMoney = pMoney
    end if

    if (vPeriod = vComma)
    or (vPeriod = vMoney)
    or (vComma  = vMoney)
    then
        -- Duplicate chars used so revert.
        vPeriod = lOldValues[1]
        vComma  = lOldValues[2]
        vMoney  = lOldValues[3]
    else
        vLegalChars = "0123456789abcdef-+" & vPeriod & vComma
    end if

    return lOldValues
end function

----------------------------------------------------------------------------
---
-- Converts a text sequence to a number (atom).
--  Leading and trailing spaces are ignored.
--  If the text is enclosed in parenthesis, a negative number is returned.
--  If the number begins with ...
--    [Money Symbol]  : base is assumed as 10
--    #  : base is assumed as 16 (Hexadecimal)
--    0x : base is assumed as 16 (Hexadecimal)
--    0b : base is assumed as 2 (Binary)
--    0d : base is assumed as 16 (Decimal)
--    0O : base is assumed as 8 (Octal)
--    x' : base is assumed as 16 (Hexadecimal) and final char is dropped
--    b' : base is assumed as 2 (Binary) and final is char dropped
--    d' : base is assumed as 16 (Decimal) and final char is dropped
--    O' : base is assumed as 8 (Octal) and final char is dropped
--
-- The text can have a single '-' or '+', either before or after the number.
-- Base 10 numbers can have digit separators. eg. 12,345.678,9
--
-- The function returns a 3-element sequence.
--  1) 0 ==> The input had some invalid format. Either a subsequence,
--              a non-integer atom,
--              or a character other than 0-9 a-f "+-", decimal or separator
symbol
--              or money symbol not in front of the number
--              or a digit not in the current number base.
--     1 ==> No invalid elements were found.
--  2) The converted number (or as much as could be converted)
--  3) The index into the input were conversion stopped. Use this as an
--     error marker if a zero was returned in the first element.
--
-- Examples:
--       sequence rc
--       rc = seqtonumber(" $2,150.95")
--       ? rc -- {1,2150.95,11}
--
--       rc = seqtonumber("1234-")
--       ? rc -- {1,-1234,6}
--
--       rc = seqtonumber("0xff73")
--       ? rc -- {1,65395,7}
--
--       rc = seqtonumber("b'001101'")
--       ? rc -- {1,13,9} (The final ' is ignored)
--
--       rc = seqtonumber("12 Cats")
--       ? rc -- {0,12,3}
--
--       rc = seqtonumber("12.3.3 Cats")
--       ? rc -- {0,12.3,5}
--

---- Valid "number" modifier prefixes.
constant kNumStarts =
        {
            {"0X", 256, 16, 0},
            {"0O", 256,  8, 0},
            {"0B",  11,  2, 0},
            {"0D",  13, 10, 0},
            {"X'", 256, 16, 1},
            {"D'", 256, 10, 1},
            {"O'", 256,  8, 1},
            {"B'", 256,  2, 1}
        }
--------------------------------------------
global function seqtonumber(sequence pData)
--------------------------------------------
    atom lResult

    integer lDotFound, lSign, lPos, lOk, lChar, lValue
    atom  lRHS, lLHS, lRHSdepth, lFullValue
    integer lBase, lUsingRHS, lCommas
    integer lStart, lEnd, lConvStarted, lTrailingSign
    sequence lTemp


    lResult = 0
    lDotFound = FALSE
    lSign = 0
    lUsingRHS = 0
    lConvStarted = FALSE
    lTrailingSign = FALSE

    lRHS = 0
    lRHSdepth = 1
    lLHS = 0
    lBase = vBase

    -- Disregard trailing and leading blanks
    lStart = length(pData) + 1
    for i = 1 to length(pData) do
        if pData[i] != ' ' then
            lStart  = i
            exit
        end if
    end for
    lEnd = 0
    for i = length(pData) to 1 by -1 do
        if pData[i] != ' ' then
            lEnd  = i
            exit
        end if
    end for

    -- Look for parenthesized numbers.
    if equal('(', pData[lStart]) and equal(')', pData[lEnd]) then
        lStart += 1
        lEnd -= 1
        lSign = -1
    end if

    -- Examine for special start codes.
    if   lEnd - lStart >= 0
    then
        if equal(vMoney, pData[lStart]) then
            -- Cater for spaces between the $ and first digit.
            for i = lStart+1 to lEnd do
                if pData[i] != ' ' then
                    lStart  = i
                    exit
                end if
            end for
            lBase = 10
        elsif equal('#', pData[lStart]) then
            lBase = 16
            lStart += 1
        elsif lStart != length(pData) then
            lTemp = upper(pData[lStart .. lStart + 1])
            for i = 1 to length(kNumStarts) do
                if equal(lTemp, kNumStarts[i][1]) then
                    if lBase < kNumStarts[i][2] then
                        lBase = kNumStarts[i][3]
                        lStart += length(kNumStarts[i][1])
                        lEnd -= kNumStarts[i][4]
                        exit
                    end if
                end if
            end for
        end if
    end if

    -- Only base-10 can have commas
    if lBase != 10 then
        lCommas = FALSE
    else
        lCommas = TRUE
    end if

    -- Start parsing the string.
    lPos = lStart
    lOk = TRUE
    while TRUE do
        -- No more characters?
        if lPos > lEnd then
            exit
        end if

        -- Check for embedded sequences
        if sequence(pData[lPos]) then
            lOk = FALSE
            exit
        end if

        -- Check for non-integer elements.
        if not integer(pData[lPos]) then
            lOk = FALSE
            exit
        end if

        -- Pluck out the next char to examine.
        lChar = lower(pData[lPos])

        -- Is it legal char.?
        lValue = find(lChar, vLegalChars) - 1
        if lValue < 0 then
            lOk = FALSE
            exit
        end if

        -- Values below the base are useable digits.
        if lValue < lBase then
            -- This prevents embedded signs.
            if lTrailingSign = TRUE then
                lOk = FALSE
                exit
            end if

            -- Signal that conversion is underway.
            lConvStarted = TRUE

            -- Am I doing the Left or Right side of the "decimal" symbol?
            if lUsingRHS then
                -- Right side.
                -- Accume that value so far.
                lRHS = (lRHS * lBase) + lValue
                -- Calculate the RHS divisor
                lRHSdepth *= lBase
            else
                -- Left side.
                -- Accume the value so far.
                lLHS = (lLHS * lBase) + lValue
            end if
        else
            -- Start checking for special symbols.

            -- A negative sign?
            if lChar = '-' then
                -- If I haven't found one yet then mark this a -ve number
                -- and if conversion had started, its a trailing sign.
                if lSign = 0 then
                    lSign = -1
                    lTrailingSign = lConvStarted
                else
                    -- Duplicate sign symbol detected.
                    lOk = FALSE
                    exit
                end if
            -- A positive sign?
            elsif lChar = '+' then
                -- If I haven't found one yet then mark this a +ve number
                -- and if conversion had started, its a trailing sign.
                if lSign = 0 then
                    lSign = 1
                    lTrailingSign = lConvStarted
                else
                    -- Duplicate sign symbol detected.
                    lOk = FALSE
                    exit
                end if
            -- A decimal position symbol?
            elsif lChar = vPeriod then
                -- If I haven't found one yet then mark that I now have
                -- and start processing the right hand side.
                if lDotFound = FALSE then
                    lDotFound = TRUE
                    lUsingRHS = TRUE
                else
                    -- A duplicate decimal symbol found.
                    lOk = FALSE
                    exit
                end if
            -- A digit separator?
            elsif lChar = vComma then
                -- If this base is not allowed digit separators, flag an
error.
                if lCommas = FALSE then
                    lOk = FALSE
                    exit
                end if
            else
            -- Must be a non-legal character for current number base.
                lOk = FALSE
                exit
            end if
        end if

        -- Bump to next input character.
        lPos += 1
    end while

    -- If no sign symbols used, assume a positive number.
    if lSign = 0 then
        lSign = 1
    end if

    -- Calculate the actual value represented by the string.
    lFullValue = lSign *(lLHS + (lRHS / lRHSdepth))

    return {lOk, lFullValue, lPos}
end function
----------------------------------

cheers,
Derek Parnell

new topic     » goto parent     » topic index » view message » categorize

7. Re: So...what if I wanted to do something like atof?

The solution I to this that I would probably implement would be:

1. Use an onChange event procedure to filter input, effectively allowing the
user to ONLY enter a properly-formatted value (dollars and cents).

2. Use value() to convert from string to numeric format. (It's only
"unusable" if you don't know, or have no control over, the format of the
data.)

This approach has the triple advantages of being extremely simple,
"professional", and bullet-proof.

What I mean by professional is that any program you buy off-the-shelf (I
hope!) would not let the user enter arbitrary letters and punctuation into a
price field. The only input allowed should be a reasonable number of decimal
digits, followed by a (perhaps optional) decimal point and exactly two
digits. This is very standard functionality that is intuitively satisfying
and has survived the test of time. Personally, I wouldn't even dream of
failing to use it.

Writing appropriate filter code isn't too challenging, so I recommend you do
it yourself pretty much from scratch, but if you prefer, I can privately
share some code I wrote that filters for numeric input (digits, optional
decimal point and more digits), from which it would be a hop/skip/jump to
the filtering you want.

Regards,
George Henry

_____________________________________________________________________________________
Get more from the Web.  FREE MSN Explorer download : http://explorer.msn.com

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu