1. Little incosistency in Euphoria 2.2
- Posted by rforno at tutopia.com Apr 26, 2001
- 401 views
While investigating the value() function and trying to mimic it, I discovered this little inconsistency: value("-45.6a-") gives {0,-45.6} but value("-45.6e-") gives {1,0}
2. Re: Little incosistency in Euphoria 2.2
- Posted by Ted Fines <fines at macalester.edu> Apr 26, 2001
- 390 views
Hmmm... Maybe I'm missing the point (likely, my wife says :)), but isn't this post regarding the value() function similar to the last one questioning how well value() worked? Similar in that they both feed value() some kind of bad data? Garbage in -> Garbage out. Maybe we're overloading value() and expecting too much? If so, shouldn't we just write a different, more robust function? I mean, how well does gets(fn) handle a bad sector on a hard disk? Should we expect it to be able to handle ANY input we throw at it? The 'we' isn't the royal we...It's the Euphoria clan 'we'. I'm including myself as I use the function too... --Ted --On Thursday, April 26, 2001 05:20:12 PM -0300 rforno at tutopia.com wrote: > > > While investigating the value() function and trying to mimic it, I > discovered this little inconsistency: > value("-45.6a-") gives {0,-45.6} > but > value("-45.6e-") gives {1,0} > > > > > >
3. Re: Little incosistency in Euphoria 2.2
- Posted by daryl_vdb at HOTMAIL.COM Apr 26, 2001
- 395 views
This is a multi-part message in MIME format. ------=_NextPart_000_003F_01C0CF0A.92CCECE0 charset="iso-8859-1" I think this is because value() thinks you were going to enter a number = with a power of ten. eg value("45.6e2") should return 4560. =20 ------=_NextPart_000_003F_01C0CF0A.92CCECE0 charset="iso-8859-1" <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML><HEAD> <META http-equiv=3DContent-Type content=3D"text/html; = charset=3Diso-8859-1"> <META content=3D"MSHTML 5.50.4522.1800" name=3DGENERATOR> <STYLE></STYLE> </HEAD> <BODY bgColor=3D#ffffff> <DIV><FONT face=3DArial size=3D2>I think this is because value() thinks = you were=20 going to enter a number with a power of ten. eg</FONT></DIV> <DIV><FONT face=3DArial size=3D2></FONT> </DIV> <DIV><FONT face=3DArial size=3D2>value("45.6e2")</FONT></DIV> <DIV><FONT face=3DArial size=3D2></FONT> </DIV> <DIV><FONT face=3DArial size=3D2>should return 4560. =20 ------=_NextPart_000_003F_01C0CF0A.92CCECE0--
4. Re: Little incosistency in Euphoria 2.2
- Posted by rolf.schroeder at desy.de Apr 26, 2001
- 407 views
To avoid errors, value() should ALWAYS return an error message in case the input string is not fully representing a number (i.e. 12345 or 1e-3). A long time ago I claimed this, but it will not be changed, for this is the bad heritage of a C-routine behind it! Have a nice day, Rolf
5. Re: Little incosistency in Euphoria 2.2
- Posted by Igor Kachan <kinz at peterlink.ru> Apr 27, 2001
- 420 views
6. Re: Little incosistency in Euphoria 2.2
- Posted by Derek Parnell <ddparnell at bigpond.com> Apr 27, 2001
- 405 views
----- Original Message ----- From: <rforno at tutopia.com> To: "EUforum" <EUforum at topica.com> Subject: RE: Little incosistency in Euphoria 2.2 > I cannot agree with you. If e- is bad, why a- is not? Because the letter 'e', when it immediately follows a series of digits, is regarded by value() to be a part of an embedded encoding of a number in scientific notation. If detected, it MUST be followed by another series of digits. If not, then value() believes you have a badly formatted number. In the case of "a-", the 'a' character signals the END of a number and is not regarded as a part of the number's notation. However, I agree that this is not the best idea. Sorry for those who don't long posts but here is an attempt I made at writing a sequence-to-number conversion. I wanted to use the function seqtonumber() in an expression so it always returns an atom. To detected errors, I've had create another function that returns the error position. Finally, it does not support scientific notation (yet). ---------------------------- 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 is dropped -- b' : base is assumed as 2 (Binary) and final is dropped -- d' : base is assumed as 16 (Decimal) and final is dropped -- O' : base is assumed as 8 (Octal) and final is dropped -- -- The text can have a single embedded '-' or '+' -- Base 10 text can have commas -- -- It returns an atom which is the converted number -- (or as much as could be converted) -- -- If an error was detected in the source string, such as a subsequence, -- a non-integer atom, or a character other than 0-9 a-f ".,+-", -- or a digit not in the current number base, then the function -- isconverr() returns the position in the string that -- contains the offending element. -- -- Examples: -- sequence rc -- rc = seqtonumber(" $2,150.95") -- --> rc = 2150.95 isconverr() --> 0 -- -- rc = seqtonumber("1234-") -- --> rc = -1234 isconverr() --> 0 -- -- rc = seqtonumber("0xff73") -- --> rc = 65395 isconverr() --> 0 -- -- rc = seqtonumber("b'001101'") -- --> rc = 13 isconverr() --> 0 -- -- rc = seqtonumber("12 Cats") -- --> rc = 12 isconverr() --> 3 -- -- rc = seqtonumber("12.3.3 Cats") -- --> rc = 12.3 isconverr() --> 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} } integer NumConvErr NumConvErr = -1 global function isconverr() return NumConvErr end function 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 NumConvErr = 0 lResult = 0 lDotFound = 0 lSign = 0 lUsingRHS = 0 lConvStarted = 0 lTrailingSign = 0 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 = 0 else lCommas = 1 end if -- Start parsing the string. lPos = lStart lOk = 1 while 1 do -- No more characters? if lPos > lEnd then exit end if -- Check for embedded sequences if sequence(pData[lPos]) then lOk = 0 exit end if -- Check for non-integer elements. if not integer(pData[lPos]) then lOk = 0 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 = 0 exit end if -- Values below the base are usable digits. if lValue < lBase then -- This prevents embedded signs. if lTrailingSign = 1 then lOk = 0 exit end if -- Signal that conversion is underway. lConvStarted = 1 -- 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 sybol detected. lOk = 0 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 sybol detected. lOk = 0 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 = 0 then lDotFound = 1 lUsingRHS = 1 else -- A duplicate decimal symbol found. lOk = 0 exit end if -- A digit separator? elsif lChar = vComma then -- If this base is not allowed digit separators, flag an error. if lCommas = 0 then lOk = 0 exit end if else -- Must be a non-legal character for current number base. lOk = 0 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)) if not lOk then NumConvErr = lPos else NumConvErr = 0 end if return lFullValue end function ---------------------------- ------ Derek Parnell Melbourne, Australia "To finish a job quickly, go slower."