e r l a n g : c o o k b o o k

/ Erlang.NumberIsNumber

This Web


WebHome 
WebChanges 
TOC
NewRecipe 
WebTopicList 
WebStatistics 

All Webs


Chicken
Cookbook
Erlang
Know
Main
Plugins
Sandbox
Scm
TWiki  

Erlang Links


Erlang.org
Erlang Wiki
ErlMan
Erlang Wiki
The Jungerl
Erlang-fr.org
Joe Armstrong
Lambda the Ultimate

Erlang Web Ring


[Prev]: Joe Armstrong's Page
[Next]: Joe Armstrong's Page

Checking Whether a String Is a Valid Number

Problem

You need to check if a given string contains a valid number.

Solution

We supose that we want to check the text strings: "42", "2+3i", "3.1416", "2/3", "hello". Erlang is trickier than Scheme, since it does not provide the native support for fractional values or imaginary numbers. However, the general algorithm we need to use is something like the following: 1 Try to convert the string to a number (of some kind). 2 Pass the resulting value to the built-in Erlang predicates is_number.

Let's see some examples:

1> is_number("42").
false
2> {ok, [Num], _} = io_lib:fread("~d", "42"), is_number(Num).
true
3> {ok, [Num2], _} = io_lib:fread("~u", "42"), is_number(Num2).
true
4> {ok, [Num3], _} = io_lib:fread("~u", "42"), is_number(Num3).
true
5> {ok, [Num4], _} = io_lib:fread("~u", "42.0"), is_number(Num4).
true
6> {ok, [Num5], _} = io_lib:fread("~f", "42.0"), is_number(Num5).
true
7> io_lib:fread("~u", "2+3i").    
{ok,[2],"+3i"}
8> {ok, [Num6], _} = io_lib:fread("~f", "3.1416"), is_number(Num6). 
true
9> io_lib:fread("~f", "2/3").    
{error,{fread,float}}
10> io_lib:fread("~f", "hello").
{error,{fread,float}}

Discussion

Clearly, Erlang's generic io_lib:fread functionality does not provide everything we want. It doesn't handle fractional values with the easy and grace of Scheme, and it does not understand imaginary numbers. However, this functionality could be provided in a library that provides an "is_number" interface similar to what we want.

We could also follow the Perl approach of using regular expressions to determine if the string is a number, but that is a topic for another Recipe.

There may also be times when you want to tell if a given number is an integer number a floating-point number. One solution is using the io_lib:fread function as before, and then using one of the Erlang built-in predicates is_integer and is_float. procedures:

13> {ok, [Val13], _} = io_lib:fread("~f", "3.0"), is_integer(Val13).
false
14> {ok, [Val14], _} = io_lib:fread("~f", "3.0"), is_float(Val14).
true
15> {ok, [Val15], _} = io_lib:fread("~u", "22"), is_integer(Val15).
true

Contributors

Based on work by ChandraQuintas.

-- BrentAFulgham - 23 Aug 2004

CookbookForm
TopicType: Recipe
ParentTopic: NumberRecipes
TopicOrder: 010

 
 
Copyright © 2004 by the contributing authors. All material on the Erlang Cookbook web site is the property of the contributing authors.
This material can be redistributed and/or modified under the terms of the GNU Lesser General Public License (LGPL), version 2.1, as published by the Free Software Foundation.
Ideas, requests, problems regarding Schematics Cookbook? Send feedback.
/ You are Main.guest