Is Number Function

DIY is_number Function

Ronald Weidner

I debated about writing this wiki page. It seems like such a simple thing to determine if a string is a number or not. But a lot can go into that question. Euphoria has a function called to_number that you can use to detect whether a string (sequence) is a number or not. For example: https://openeuphoria.org/docs/std_convert.html#_2293_to_number

include std/convert.e 
sequence some_str = "-0.5" 
if atom(to_number(some_str, -1)) then 
    atom num = to_number(some_str) 
end if 

If you don't like reinventing the wheel, just use the Euphoria code above to check strings for numbers. But, if you're more like me and want to take a stab at writing a function that can specialize in that functionality... read on.

The to_number function takes 2 arguments. The first is a sequence. The second modifies the output of the function. Sometimes the output is an atom, sometimes a 1-element sequence, and sometimes a 2-element sequence. But honestly, all I really want sometimes is just a true or false... Is this thing a number or not? That's what is_number tries to do. My use case for checking numbers is usually a base-10, signed float or integer. In the future I might write a function named is_number_exp(sequence s, sequence flags) that does more than this function does. It might handle money, percentages, commas, etc. Not because to_number can't already do that, but rather because I like doing those kinds of things.

include std/convert.e 
include std/sequence.e 
 
-- Returns 1 if the string is a valid, undecorated base-10 number (e.g., "42", "-3.14", ".5") 
-- Returns 0 otherwise. 
--  
-- Notes: 
-- - No commas, exponents, or hex/octal prefixes allowed. 
-- - Leading + or - is allowed. 
-- - A leading or trailing decimal point is valid (e.g., ".5", "5."). 
-- - Empty strings, multiple dots, or non-digit characters cause failure. 
function is_number(sequence maybe) 
    integer found_dot = 0 
    integer i = 1 
    integer c = 0 
    integer retval = 0 
     
    -- because empty string is not a number 
    if length(maybe) = 0 then 
        return 0 
    end if 
     
    -- we'll skip the sign if it has one 
    if find(maybe[i], "+-") then 
        i += 1 
    end if 
     
    -- We might have just moved the index.  Make sure there is at  
    -- least 1 more character to consider. 
    if i > length(maybe) then 
        return 0 
    end if 
     
    -- if nothing follows a leading . maybe isn't a number 
    if equal(maybe[i], '.') and (i + 1 > length(maybe)) then 
        return 0 
    end if 
     
    -- At this point i is either 1 or 2.  It's 1 if there is no sign. It's 
    -- 2 if there is a sign.  maybe[i] might be a . but it might not be. 
    -- If it is a dot at least one more char is required in a valid string.   
    -- Let's say we have this string.  "+.." .  In that 
    -- case i is 2 when we enter the loop.  We'll set retval to 1 and  
    -- consume the first . .  The first . is valid. Let's start consuming  
    -- the rest of the string.  Anything other than a digit is invalid.   
    -- 
    -- I believe this loop should be able to accurately determine whether or 
    -- not a string is a base-10 undecorated number.  Edge cases are already  
    -- dealt with. Looks good on my monitor. 
    while i < (length(maybe) + 1) do 
        c = maybe[i] 
        if equal(c, '.') and found_dot then 
            return 0 
        end if 
 
        if equal(c, '.') then  
            found_dot = 1 
        elsif not find(c, "0123456789") then 
            return 0 
        end if 
        retval = 1 
        i+=1 
    end while 
    return retval 
end function 
 
-- Sequence return will be at least and no more than  
-- len characters long.  if length(s) < len the 
-- difference will be right padded with spaces. 
-- If length(s) > len then the return value will be a  
-- truncated version of s. 
function fixed_len(sequence s, integer len) 
    if length(s) < len then 
        return s & repeat(' ', len - length(s)) 
    end if 
    return s[1..len] 
end function 
 
sequence false_tests = {" ", ".", "-", "+", "..", ".-", ".+", 
"-.", "+.", "0..", ".0.", "--", "++", "1 4", "A", "-a", "+a", 
"-.a", "+.a", ".a", "1a", ".1a ", "7+", "7-", "7Foo", "7*" 
} 
 
sequence true_tests = { "0", "0.", ".0", "-.0", "+.0", "0.0", 
"-0.0", "+0.0", "123", "123.", ".123", "-.123", "+.123","123.123", 
"-123.123", "+123.123", "00032", "-00032", "+00032", "00032.000", "-00032.050",  
"+00032.0", "00000.0000", "-00000.0000" 
} 
 
integer i = 1 
puts (1, "Testing for FALSE (0): \n") 
while i < length(false_tests) + 1 do 
    sequence t = false_tests[i] 
    sequence msg = fixed_len(sprintf("Testing is_number function with input [%s] ",{t} ),55) 
    printf(1, msg & "result: [%d]\n" , {is_number(t)}) 
    i += 1 
end while 
 
i = 1 
puts (1, "Testing for TRUE (1): \n") 
while i < length(true_tests) + 1 do 
    sequence t = true_tests[i] 
    sequence msg = fixed_len(sprintf("Testing is_number function with input [%s] ",{t} ), 55) 
    printf(1, msg & "result: [%d]\n" , {is_number(t)}) 
    i += 1 
end while 
 
puts(1,"\n\nWhat would Euphoria do??  atom d = atom(to_number(test_str, -1)) \n\n") 
 
i = 1 
puts (1, "Testing for FALSE (0): \n") 
while i < length(false_tests) + 1 do 
    sequence t = false_tests[i] 
    sequence msg = fixed_len(sprintf("What would Euphoria do with input [%s] ",{t} ),55) 
    printf(1, msg & "result: [%d]\n" , {atom(to_number(t, -1))}) 
    i += 1 
end while 
 
i = 1 
puts (1, "Testing for TRUE (1): \n") 
while i < length(true_tests) + 1 do 
    sequence t = true_tests[i] 
    sequence msg = fixed_len(sprintf("What would Euphoria do with input [%s] ",{t} ),55) 
    printf(1, msg & "result: [%d]\n" , {atom(to_number(t, -1))}) 
    i += 1 
end while 
 

$ eui is_number.ex 
Testing for FALSE (0): 
Testing is_number function with input [ ]              result: [0] 
Testing is_number function with input [.]              result: [0] 
Testing is_number function with input [-]              result: [0] 
Testing is_number function with input [+]              result: [0] 
Testing is_number function with input [..]             result: [0] 
Testing is_number function with input [.-]             result: [0] 
Testing is_number function with input [.+]             result: [0] 
Testing is_number function with input [-.]             result: [0] 
Testing is_number function with input [+.]             result: [0] 
Testing is_number function with input [0..]            result: [0] 
Testing is_number function with input [.0.]            result: [0] 
Testing is_number function with input [--]             result: [0] 
Testing is_number function with input [++]             result: [0] 
Testing is_number function with input [1 4]            result: [0] 
Testing is_number function with input [A]              result: [0] 
Testing is_number function with input [-a]             result: [0] 
Testing is_number function with input [+a]             result: [0] 
Testing is_number function with input [-.a]            result: [0] 
Testing is_number function with input [+.a]            result: [0] 
Testing is_number function with input [.a]             result: [0] 
Testing is_number function with input [1a]             result: [0] 
Testing is_number function with input [.1a ]           result: [0] 
Testing is_number function with input [7+]             result: [0] 
Testing is_number function with input [7-]             result: [0] 
Testing is_number function with input [7Foo]           result: [0] 
Testing is_number function with input [7*]             result: [0] 
Testing for TRUE (1): 
Testing is_number function with input [0]              result: [1] 
Testing is_number function with input [0.]             result: [1] 
Testing is_number function with input [.0]             result: [1] 
Testing is_number function with input [-.0]            result: [1] 
Testing is_number function with input [+.0]            result: [1] 
Testing is_number function with input [0.0]            result: [1] 
Testing is_number function with input [-0.0]           result: [1] 
Testing is_number function with input [+0.0]           result: [1] 
Testing is_number function with input [123]            result: [1] 
Testing is_number function with input [123.]           result: [1] 
Testing is_number function with input [.123]           result: [1] 
Testing is_number function with input [-.123]          result: [1] 
Testing is_number function with input [+.123]          result: [1] 
Testing is_number function with input [123.123]        result: [1] 
Testing is_number function with input [-123.123]       result: [1] 
Testing is_number function with input [+123.123]       result: [1] 
Testing is_number function with input [00032]          result: [1] 
Testing is_number function with input [-00032]         result: [1] 
Testing is_number function with input [+00032]         result: [1] 
Testing is_number function with input [00032.000]      result: [1] 
Testing is_number function with input [-00032.050]     result: [1] 
Testing is_number function with input [+00032.0]       result: [1] 
Testing is_number function with input [00000.0000]     result: [1] 
Testing is_number function with input [-00000.0000]    result: [1] 
 
 
What would Euphoria do??  atom d = atom(to_number(test_str, -1)) 
 
Testing for FALSE (0): 
What would Euphoria do with input [ ]                  result: [0] 
What would Euphoria do with input [.]                  result: [0] 
What would Euphoria do with input [-]                  result: [0] 
What would Euphoria do with input [+]                  result: [0] 
What would Euphoria do with input [..]                 result: [0] 
What would Euphoria do with input [.-]                 result: [0] 
What would Euphoria do with input [.+]                 result: [0] 
What would Euphoria do with input [-.]                 result: [0] 
What would Euphoria do with input [+.]                 result: [0] 
What would Euphoria do with input [0..]                result: [0] 
What would Euphoria do with input [.0.]                result: [0] 
What would Euphoria do with input [--]                 result: [0] 
What would Euphoria do with input [++]                 result: [0] 
What would Euphoria do with input [1 4]                result: [0] 
What would Euphoria do with input [A]                  result: [0] 
What would Euphoria do with input [-a]                 result: [0] 
What would Euphoria do with input [+a]                 result: [0] 
What would Euphoria do with input [-.a]                result: [0] 
What would Euphoria do with input [+.a]                result: [0] 
What would Euphoria do with input [.a]                 result: [0] 
What would Euphoria do with input [1a]                 result: [0] 
What would Euphoria do with input [.1a ]               result: [0] 
What would Euphoria do with input [7+]                 result: [1] 
What would Euphoria do with input [7-]                 result: [1] 
What would Euphoria do with input [7Foo]               result: [0] 
What would Euphoria do with input [7*]                 result: [0] 
Testing for TRUE (1): 
What would Euphoria do with input [0]                  result: [1] 
What would Euphoria do with input [0.]                 result: [1] 
What would Euphoria do with input [.0]                 result: [1] 
What would Euphoria do with input [-.0]                result: [1] 
What would Euphoria do with input [+.0]                result: [1] 
What would Euphoria do with input [0.0]                result: [1] 
What would Euphoria do with input [-0.0]               result: [1] 
What would Euphoria do with input [+0.0]               result: [1] 
What would Euphoria do with input [123]                result: [1] 
What would Euphoria do with input [123.]               result: [1] 
What would Euphoria do with input [.123]               result: [1] 
What would Euphoria do with input [-.123]              result: [1] 
What would Euphoria do with input [+.123]              result: [1] 
What would Euphoria do with input [123.123]            result: [1] 
What would Euphoria do with input [-123.123]           result: [1] 
What would Euphoria do with input [+123.123]           result: [1] 
What would Euphoria do with input [00032]              result: [1] 
What would Euphoria do with input [-00032]             result: [1] 
What would Euphoria do with input [+00032]             result: [1] 
What would Euphoria do with input [00032.000]          result: [1] 
What would Euphoria do with input [-00032.050]         result: [1] 
What would Euphoria do with input [+00032.0]           result: [1] 
What would Euphoria do with input [00000.0000]         result: [1] 
What would Euphoria do with input [-00000.0000]        result: [1] 
 
 

Not Categorized, Please Help

Search



Quick Links

User menu

Not signed in.

Misc Menu