Is a value a decimal number or not?

T

Tore Aursand

Hi!

Not having written many tests myself, I started yesterday looking av some
of the Test modules. Boring stuff, but an excellent way of keeping your
code clean from those annoying bugs.

However. In one of the modules, there was a 'is_decimal' function, and it
failed some of my tests. Not surprisingly, though. But. Is there a way
to check if a number is a decimal number even when you declare the value
as a "plain number"?

Example:

my $nr = 5.00;

if ( is_decimal($nr) ) {
print "is_decimal\n";
}

sub is_decimal {
my $nr = shift;
return ( defined $nr && $nr =~ m,^[+-]?(\d+)?\.\d+$, ) ? 1 : 0;
}

This always fails, of course, as Perl seems to evaluate _the number_ 5.00
as the number 5 as soon as the variable $nr gets set. Setting $nr to a
string - ie. '5.00' - works fine.

Is there a way round this "problem"? No big deal, really, but just out of
curiousity. :)
 
J

Josef Möllers

Tore said:
Hi!

Not having written many tests myself, I started yesterday looking av some
of the Test modules. Boring stuff, but an excellent way of keeping your
code clean from those annoying bugs.

However. In one of the modules, there was a 'is_decimal' function, andit
failed some of my tests. Not surprisingly, though. But. Is there a way
to check if a number is a decimal number even when you declare the value
as a "plain number"?

Example:

my $nr = 5.00;

if ( is_decimal($nr) ) {
print "is_decimal\n";
}

sub is_decimal {
my $nr = shift;
return ( defined $nr && $nr =~ m,^[+-]?(\d+)?\.\d+$, ) ? 1 : 0;
}

This always fails, of course, as Perl seems to evaluate _the number_ 5.00
as the number 5 as soon as the variable $nr gets set. Setting $nr to a
string - ie. '5.00' - works fine.

Is there a way round this "problem"? No big deal, really, but just outof
curiousity. :)

It's not really a "problem", but you give the solution yourself: you're
mixing apples with oranges.
You assign a number to a variable, but do a string test on it. Perl does
a lot of stringification for you (as I have learned only yesterday), but
when it sees "$nr = 5.00", it first parses the string "5.00" itself and
converts it to its internal representation of a number. As this number
has no decimals, stringification of it will return "5", as this is the
simplest representation of 5.00.


[X] I don't know Perl
... but then ... who does?
 
A

Anno Siegel

Tore Aursand said:
Hi!

Not having written many tests myself, I started yesterday looking av some
of the Test modules. Boring stuff, but an excellent way of keeping your
code clean from those annoying bugs.

However. In one of the modules, there was a 'is_decimal' function, and it
failed some of my tests. Not surprisingly, though. But. Is there a way
to check if a number is a decimal number even when you declare the value
as a "plain number"?

What do you consider a decimal number?

Numbers as such aren't decimal or binary or anything, they're numbers.
Various systems can be used to represent numbers *as strings*, and that
is what properties like "hex", "binary" and "decimal" are talking about.
So the distinction is about strings, not the numbers they represent.
Example:

my $nr = 5.00;

if ( is_decimal($nr) ) {
print "is_decimal\n";
}

sub is_decimal {
my $nr = shift;
return ( defined $nr && $nr =~ m,^[+-]?(\d+)?\.\d+$, ) ? 1 : 0;

Why the "?:" operator? It doesn't change the boolean result.

It seems you require a period in a string for it to count as a "decimal
number". That is not the usual definition, though I know one participant
on clpm who would agree with you. In the usual definition a string is
a decimal number if it consists of an optional sign, one or more digits
and at most one period among the digits. I suppose that's what is_decimal()
checks, though I haven't looked.
This always fails, of course, as Perl seems to evaluate _the number_ 5.00
as the number 5 as soon as the variable $nr gets set. Setting $nr to a
string - ie. '5.00' - works fine.

Is there a way round this "problem"? No big deal, really, but just out of
curiousity. :)

There is no problem. A number is a number, and the question whether it
is decimal makes no sense. You can write the same number in different
ways, and with these routines like is_decimal() give reasonable answers.

Anno
 
T

Tore Aursand

What do you consider a decimal number?

As <http://www.shodor.org/interactivate/dictionary/d.html> states:

"A fraction where the denominator is a power of ten and is therefore
expressed using a decimal point. For example: 0.37 is the decimal
equivalent of 37/100."
sub is_decimal {
my $nr = shift;
return ( defined $nr && $nr =~ m,^[+-]?(\d+)?\.\d+$, ) ? 1 : 0;
}
Why the "?:" operator? It doesn't change the boolean result.

Hmm. Don't know; I didn't write the code. Personally, I would've skipped
it;

sub is_decimal {
my $nr = shift;
return ( defined $nr && $nr =~ /.../ );
}

That's not the point, though.
It seems you require a period in a string for it to count as a "decimal
number". That is not the usual definition, though I know one
participant on clpm who would agree with you.

Only _one_ who agrees with me!? :) Yes, I would like to think of a
decimal number as something express with a decimal point (period), as
mentioned in the dictionary definition.
In the usual definition a string is a decimal number if it consists of
an optional sign, one or more digits and at most one period among the
digits.

Optional sign, optional digits, at most one period and one or more digits.

Anyway; This topic was really a digression. I just got curious if it was
possible to re-evaluate (or whatever) '$i = 5.00' and state that it _is_ a
decimal number (or whatever you prefer to call it).
 
J

Josef Möllers

Tore said:
Only _one_ who agrees with me!? :) Yes, I would like to think of a
decimal number as something express with a decimal point (period), as
mentioned in the dictionary definition.

A "decimal number" is a representation of a number with a base 10 (in
contrast to hexadecimal, octal and binary numbers).

A number with a decimal point, however, is said to "have decimals", it
is a "number with decimals", i.e. there are digits after the decimal
point.

That's the difference, but then ... I'm not a native english speaker.

Josef
 
A

Anno Siegel

Anyway; This topic was really a digression. I just got curious if it was
possible to re-evaluate (or whatever) '$i = 5.00' and state that it _is_ a
decimal number (or whatever you prefer to call it).

No. "$x = 5.00" and "$x = 5" are indistinguishable after the fact.
That is *why* it makes little sense to exclude whole numbers from the
set of decimal numbers.

Anno
 
T

Tassilo v. Parseval

Also sprach Anno Siegel:
No. "$x = 5.00" and "$x = 5" are indistinguishable after the fact.
That is *why* it makes little sense to exclude whole numbers from the
set of decimal numbers.

In fact, no, they shouldn't be indistinguishable:

ethan@ethan:~$ perl -MDevel::peek
Dump(5);
Dump(5.0);
__END__
SV = IV(0x812b058) at 0x811e408
REFCNT = 1
FLAGS = (IOK,READONLY,pIOK)
IV = 5
SV = NV(0x812dfb0) at 0x8128ab0
REFCNT = 1
FLAGS = (NOK,READONLY,pNOK)
NV = 5

Stress is on "shouldn't". I am not sure whether there is a way to call
the various macros (SvNOK, SvIOK etc.) from pure-Perl. Maybe there's
some module around that exposes them. At least it isn't in the latest
Scalar::Util where they'd probably belong.

Tassilo
 
A

Anno Siegel

Tassilo v. Parseval said:
Also sprach Anno Siegel:


In fact, no, they shouldn't be indistinguishable:

ethan@ethan:~$ perl -MDevel::peek

No fair, peeking!
Dump(5);
Dump(5.0);
__END__
SV = IV(0x812b058) at 0x811e408
REFCNT = 1
FLAGS = (IOK,READONLY,pIOK)
IV = 5
SV = NV(0x812dfb0) at 0x8128ab0
REFCNT = 1
FLAGS = (NOK,READONLY,pNOK)
NV = 5

Stress is on "shouldn't". I am not sure whether there is a way to call
the various macros (SvNOK, SvIOK etc.) from pure-Perl. Maybe there's
some module around that exposes them. At least it isn't in the latest
Scalar::Util where they'd probably belong.

I don't think the difference between IOK and NOK is anywhere visible
in pure Perl. The problem is that, since Perl lacks a formal specification,
nobody knows what "pure Perl" is.

In any case, the difference is in the internal representation of the
numbers -- a subject I had hoped to keep out of this discussion of
"decimals". Conceptually, there is no difference between 1 and 1.0.

Anno

Anno
 
B

Ben Morrow

In any case, the difference is in the internal representation of the
numbers -- a subject I had hoped to keep out of this discussion of
"decimals". Conceptually, there is no difference between 1 and 1.0.

There can be. There is no difference between 1-as-a-member-of-the-
set-of-reals and 1.0-as-a-member-of-the-set-of-reals. But 1-as-a-
member-of-the-set-of-integers is a quite different beast. For
instance, there is no such thing as the '1.0'th element of an array,
for that would imply that there was also a '1.1'th element, which is
clearly nonsense.

Sorry, as a mathematician I tend to be a little picky about such
things :).

Ben
 
J

John Stanley

... For
instance, there is no such thing as the '1.0'th element of an array,
for that would imply that there was also a '1.1'th element, which is
clearly nonsense.

Furthermore, there is a serious difference in the physical sciences
between 1 and 1.0, as the former says that the measurement was done
to only one significant figure and the latter has two. For the former,
the true value is somewhere between .5 and 1.49+, while for the latter,
the real value is between .95 and 1.049+. The difference is an order
of magnitude.
 
A

Anno Siegel

Ben Morrow said:
There can be. There is no difference between 1-as-a-member-of-the-
set-of-reals and 1.0-as-a-member-of-the-set-of-reals. But 1-as-a-
member-of-the-set-of-integers is a quite different beast. For
instance, there is no such thing as the '1.0'th element of an array,
for that would imply that there was also a '1.1'th element, which is
clearly nonsense.

Here it is my turn to argue that, for any real x, "the x-th element of
an array" can be quite meaningful, if we extend the meaning of "array"
sufficiently. Hashes do that, in some ways.
Sorry, as a mathematician I tend to be a little picky about such
things :).

As a co-mathematician I agree that "no conceptual difference" was saying
the wrong thing.

Mathematics builds the number system in conventional steps:
natural -> integer -> rational -> real -> complex. At each step,
the newly introduced "numbers" have little to do with what was known
as numbers before, they are not only conceptually, but structurally
different.

However, after each step, mathematics goes out of its way to embed
(isomorphically) the old, smaller system into the new one, doing away
with structural differences. For instance, constructing the rationals
from the integers, these become just part of the newly constructed
rationals. Thus "1 = 1.0", and not only "consider_as_real( 1) = 1.0".

What I should have said is that "1" and "1.0" denote the same number (as
do "0x01", and a lot of other strings, under common conventions). After
mapping the strings to numbers, the values can't be distinguished.

It would have been correct to say the difference between 1 and 1.0
is *only* conceptual.

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,763
Messages
2,569,563
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top