Re: Getting different results with $var++ and $var += 1
by ikegami (Patriarch) on Dec 03, 2008 at 07:07 UTC
|
use Devel::Peek qw( Dump );
Dump($retail_rate);
Dump($coupon);
| [reply] [d/l] |
Re: Getting different results with $var++ and $var += 1
by jczeus (Monk) on Dec 03, 2008 at 07:52 UTC
|
Have you tried to retrieve the float values from the database by specifying the type?
use DBI qw(:sql_types);
...
$sth->bind_param(1, $value, { TYPE => SQL_FLOAT });
Although it probably wasn't your decision, I must also say that storing currency values as floats in databases/spreadsheets is generally a bad idea. Integral types are prefable, i.e. don't store dollars, but cents, 1/10 cents or whatever. | [reply] |
|
|
Yeah, it probably was my decision actually. Feel free to point and laugh.
It's listed as type decimal (10,2), so not a float. Sorry about that.
I'm interested in why integral types are preferred for currency. I know it's off topic, but I'd be interested in learning more about why you have this preference (or really, why I should have this preference).
| [reply] |
|
|
Ah. The old decimal fraction in binary floating point malarkey.
The reason for prefering to hold currency as, say, pennies or cents is that it ensures that the value is exact. If you hold the pennies or cents as a fraction in binary floating point, it is unlikely to be exact.
For example, when decimal 1.51 is converted to a binary fraction the result is:
1.1000_0010_1000_1111_0101_1100_0010_1000_1111_0101_1100_0010_1000_1111_0101_1100_0010_1000_1111_0101...
which you can see is a repeating binary fraction, some part of which will be rounded off.
Most decimal fractions are like this... so before any errors can be introduced by rounding and what not in any arithmetic you go on to do, most decimal fractions have a built-in "representation" error.
Much of the time you won't see the "representation" error, because conversion back to decimal rounds it off. This can lead to bafflement when two values look the same when printed out, but fail $x == $y.
Addition and subtraction are the more difficult floating point operations, so you're more likely to see the problems there. Consider: print 1.09 - 1, "\n" ;
print "0.84 - 0.34 == ", 0.84 - 0.34,
( 0.84 - 0.34 == 0.5 ? " ==" : " but !=" ), " 0.5\n" ;
which gives:
0.0900000000000001
0.84 - 0.34 == 0.5 but != 0.5
it really makes me wonder why we persist in using binary floating point for decimal arithmetic !
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
Re: Getting different results with $var++ and $var += 1
by gone2015 (Deacon) on Dec 03, 2008 at 14:06 UTC
|
It's hard to get a NaN out of an add operation, unless at least one operand is itself a NaN, or both are inf of opposite sign. On my machine (perl 5.10.0) I note that when I do get a NaN it's spelt 'nan'.
Consensus appears to be that whatever is going on here, it's to do with what my $retail_rate = $self->{'TOUR'}->{'RATE'}{$rateid}{'retail_rate'}; did, notwithstanding the fact that the result prints as 109.98. Odds are there's some magic or some overloading involved here.
| [reply] [d/l] [select] |
Re: Getting different results with $var++ and $var += 1
by trwww (Priest) on Dec 03, 2008 at 12:03 UTC
|
Hello,
The way you "force (a scalar) to float context" in perl is simply use it in numeric context (construct an expression that would require the scalar be used as a number). So the += 0 stuff isn't necessary.
Anywhoo, what you are trying to do works fine in general so you have something funky going on in your code, and you haven't given us enough information to suggest a solution:
$ perl
use warnings;
use strict;
my $retail_rate = 109.98;
my $coupon = 10.05;
my $discounted_rate = $retail_rate + 1;
print "$retail_rate $coupon $discounted_rate\n";
Ctrl-D
109.98 10.05 110.98
Hope this helps,
trwww | [reply] |
|
|
Every time I've ever used a scalar in numeric context in the past it has worked. The +=0 stuff may be unnecessary, but I'm desperate enough to try unnecessary things. I've never had to struggle for hours in order to add two numbers.
Since I posted last night, I got a response to a private request for help that indicates that $var++ just increments without assignment. So is it possible for the ++ operator to increment a value that cannot be seen in numeric context? It's a stretch of my imagination, but I'm open to the idea that it's only a stretch of my imagination because my understanding is stunted.
| [reply] |
|
|
So is it possible for the ++ operator to increment a value that cannot be seen in numeric context?
Numerical context refers to the conversion of an operand's value to a number by operators that work on numbers. Perl can get a number from any value. The process might result in a warning and the result might be useless, but it will always end up with a number. That means there is no value that cannot be seen in numeric context. That means your question doesn't make sense.
On a side note, "++" handles strings differently than other values.
>perl -wle"$a='a'; print $a+=1"
Argument "a" isn't numeric in addition (+) at -e line 1.
1
>perl -le"$a='a'; print ++$a"
b
| [reply] [d/l] |
|
|
The question is: "Is it a simple scalar, or is it an object?". Giving the output ikegami asked for could help a lot in resolving the problem.
Simple scalars behave as you expect. Objects can do whatever they like. Showing us sample that we can run and reproduce the issue would help - we could then try ikegami's test. That doesn't at all mean we want to see your application though, but just enough lines to reproduce the issue. See I know what I mean. Why don't you? for some tips that help in this situation.
Perl's payment curve coincides with its learning curve.
| [reply] [d/l] |
|
|
|
|
|
Re: Getting different results with $var++ and $var += 1
by JavaFan (Canon) on Dec 03, 2008 at 10:14 UTC
|
Could you post some code that people can actually run and get the same results? The code you post doesn't show where the values come from. | [reply] |
|
|
Well, I'm skeptical that it would be a good idea for me to upload my Order and Tour object libraries, and I don't expect anyone to sift through all my code and debug it for me. What I'm looking for is a good direction in which to direct my diagnostic efforts. Under what conditions can I take a string "110.98" and not be able to use it in numeric context? I thought the answer was "under no conditions ever for any reason under any version of Perl" but clearly I'm wrong.
That said, I'll chop out the code that spits out the values and isolate them and try to get a manageable test case.
| [reply] |
|
|
| [reply] |
|
|
I didn't suggest in anyway you post an enormous program here.
What I suggest is that you reduce your code to a minimal program such that it 1) runs, and 2) shows your problem.
Under what conditions can I take a string "110.98" and not be able to use it in numeric context? I thought the answer was "under no conditions ever for any reason under any version of Perl" but clearly I'm wrong.
Oh, no, you are right. If you have a string "110.98", you will be able to use it in numeric context. The problem however is that you may very well have some else than a string.
But since we don't know where the thing you have is coming from, we don't know, do we? And I don't like the game of "I've problem. I only half describe it. Now guess what's going on". If I want to play situation puzzles, I'll go to rec.puzzles.
| [reply] |
|
|