# turn a dollar value like $64,000.01 into 64000.01
# to allow easy accurate comparisons...
sub num {
my $num = shift;
$num =~ m/([\d\.,]+)/; # grab the digits . and ,
$num = $1 || 0;
$num =~ s/,//g; # remove the , chars
return $num; # return the normailzed number
}
print "OK" if num('$2,000.01') > num('$2000');
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
| [reply] [d/l] |
Without posting your code, it's tough to be sure what's going on here, but it appears that you are confusing a display format with an internal one. In other words, you would only want the dollar sign on the number for display purposes.
perl -e 'if ( q|$201.00| > q|$200| ) {print 1}else{print 0}'
That prints zero, which is correct, but may not be what you expect. Either strip the dollar sign or use a regex to extract the number into another variable.
Cheers,
Ovid
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] [d/l] |
So you mean if ($var1 > $var2) { ... } will compare the formats without any problem? That is if there is no dollar sign, is that what youre saying?
Doesnt it "crash" with the "." or "," when comparing? I thought numbers had to be plan integers to compare. Such as 52 > 56
Tnx
| [reply] |
Your insticts were correct to use if ( $var1 > $var2 ) {...}. Let me explain this in a bit more detail.
Perl's typing is based around data structures (scalars, arrays, hashes, etc) and not data types. Other languages that use typing typically use things like int, float, char, etc. Perl also deals with things like that, but does it behind the scenes. When dealing with a string, if you try to perform mathematical operations on it, Perl will (usually¹) try to convert the string to a number and perform the mathematical operations. If a string can't be converted to a number, it's considered to be "zero". For example, here's a little blow to my ego:
$ perl -e 'print "Ovid" + 0'
0
When you try to compare a string with a dollar sign, Perl sees the dollar sign and just converts the string to a zero. For my example above, you may have been mislead (my $apologies). When comparing strings, you would use the string comparison operators such as gt, ge, lt, and le. However, since those are comparing strings and not numbers, your results will not be suitable for mathematical operations.
So, Perl will not "crash" when you have a "." or "," in your string. The period will be recognized as a decimal point. There is one thing to be wary of, though: when trying to convert a string to a number, Perl still take the numbers at the beginning of string and use those:
$ perl -e 'print "123Ovid" + 4'
127
So, you either need to strip those dollar signs from your strings or not add those dollar signs until you're ready to output them to a file, report, screen, etc.
Cheers,
Ovid
1. The unary increment (++) and (--) decrement operators are counter-examples.
Join the Perlmonks Setiathome Group or just click on the the link and check out our stats. | [reply] [d/l] [select] |
A longer example, perhaps a little more readable, although
not as efficient as Ovid's:
if (is_greater_than($ARGV[0],$ARGV[1]))
{
print "TRUE";
}
else
{
print "FALSE";
}
sub is_greater_than
{
my ($a,$b) = @_;
return (to_num($a) > to_num($b));
}
sub to_num
{
my $val = shift;
$val =~ s/[\$,]//g;
return ($val * 100);
}
Desert coder | [reply] [d/l] |
You need to normalize the amounts before comparing them. Translate the input ($64,000 or $64,000.00 or $6400) to a standard number (6400) and then the comparison will work. | [reply] |
Iam a newbie..
So how do i translate them to a standard number?
| [reply] |
The simplest, quickest, least-learning-anything no-fun way to do what you want, I think, is to add the following two lines of code immediately after you take input:
$your_money_scalar =~ s/^\$//;
$your_money_scalar =~ s/,//g;
The first line removes a dollar sign at the beginning of a line.
The second removes all commas. | [reply] [d/l] |
epaphus2,
Others have given you good advice - especially about normalizing the data. I would add my 2 cents and also say
you should convert your monetary values to integers:
$a = 12.02;
$b = 24.32;
$a = int( $a* 100 );
$b = int( $b * 100 );
print ($a + $b)/100, "\n";
Having done real-time currency conversions for e-commerce
sites I can say there at least two things to consider when working with monetary values:
1. the above normalization works fine for most major monetary systems but would fail for others (correct me if I'm recalling wrong or things have changed but some middle east monetary systems are one-thousandths based not one-hundredths)
2. normalizing to integers will break big time for real large monetary values (I wouldn't like to figure out the US national debt with this system - nor the burn rate of a lot of dot-coms).
Those being said, if your monetary domain is straight-forward your life will be easier if you convert to integers.
-derby | [reply] [d/l] |
You should probably take a look at the module Math::Currency module available at CPAN. It may be able to do a lot of the things you're looking for without having to do any extra work. | [reply] |