Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Compare, two identical numbers are not the same?!

Reply
Thread Tools

Compare, two identical numbers are not the same?!

 
 
Justin C
Guest
Posts: n/a
 
      06-29-2009

This one is really confusing me. I have a comparison:

$totalIndividualWeights != $param{weight}

and when they're both 42.6 (probably other numbers too, but this is the
problem someone has, and has come to me with) Perl says they're not the
same:

my $totalIndividualWeights = addIndividualWeights();

if ($totalIndividualWeights != $param{weight}){
print "Weight does not add up to total weight given on the first form.\$totalIndividualWeights = $totalIndividualWeights \n \$param{weight} = $param{weight}";
}

The print statement says both weights are 42.6. $param{weight} was
input by the user, $totalIndividualWeights is reached by adding several
user inputs: 2.86, 9.94, 9.98, 9.88, 9.94

Does perl have a problem with empty decimal places? What I mean is, the
inputs are to two decimals, but the result is only using one, is perl
thinking "42.60" and not matching 42.6?

Thank you for any help you can give with this.

Justin.

--
Justin C, by the sea.
 
Reply With Quote
 
 
 
 
Jürgen Exner
Guest
Posts: n/a
 
      06-29-2009
Justin C <(E-Mail Removed)> wrote:
>
>This one is really confusing me. I have a comparison:
>
>$totalIndividualWeights != $param{weight}
>
>and when they're both 42.6 (probably other numbers too, but this is the
>problem someone has, and has come to me with) Perl says they're not the
>same:


You forgot the first commandment of computer numerics:

Thou shalt not use equality for floating point numbers!

See 'perldoc -q 9999' for further details. Although those seem to be
unrelated questions/issues in fact they have the same underlying reason
which applies to virtually all programming languages.

>The print statement says both weights are 42.6


Try printing them with 20 digits:
printf("%.20f", $totalIndividualWeights)
You may be surprised.

jue
 
Reply With Quote
 
 
 
 
Jürgen Exner
Guest
Posts: n/a
 
      06-30-2009
Glenn Jackman <(E-Mail Removed)> wrote:
>At 2009-06-29 12:24PM, "Justin C" wrote:
>> The print statement says both weights are 42.6. $param{weight} was
>> input by the user, $totalIndividualWeights is reached by adding several
>> user inputs: 2.86, 9.94, 9.98, 9.88, 9.94

>
>I addition to all the better advice, did you chomp() your user input?
>Are you comparing "42.6\n" to a number that's close to 42.6?


If that were the case then he should have gotten a warning about
non-numerical value used in numerical comparison. At least if he had
used warnings.

Technically it doesn't matter. He is using numerical compare "=", thus
Perl uses the arguments in numerical context and therefore automatically
converts the string "42.6\n" into the numerical floating point value
42.6 resp. something very close to it.

jue
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      06-30-2009
Tad J McClellan <(E-Mail Removed)> wrote:
>Jürgen Exner <(E-Mail Removed)> wrote:
>> Glenn Jackman <(E-Mail Removed)> wrote:
>>>At 2009-06-29 12:24PM, "Justin C" wrote:
>>>> The print statement says both weights are 42.6. $param{weight} was
>>>> input by the user, $totalIndividualWeights is reached by adding several
>>>> user inputs: 2.86, 9.94, 9.98, 9.88, 9.94
>>>
>>>I addition to all the better advice, did you chomp() your user input?

>
>> If that were the case then he should have gotten a warning about
>> non-numerical value used in numerical comparison. At least if he had
>> used warnings.

>
>No, there is no warning for trailing whitespace.


I stand corrected.

jue
 
Reply With Quote
 
Justin C
Guest
Posts: n/a
 
      06-30-2009
On 2009-06-29, Jürgen Exner <(E-Mail Removed)> wrote:
> Justin C <(E-Mail Removed)> wrote:
>>
>>This one is really confusing me. I have a comparison:
>>
>>$totalIndividualWeights != $param{weight}
>>
>>and when they're both 42.6 (probably other numbers too, but this is the
>>problem someone has, and has come to me with) Perl says they're not the
>>same:

>
> You forgot the first commandment of computer numerics:
>
> Thou shalt not use equality for floating point numbers!


Being self-taught this had passed me by (I'm not qualified to teach
Perl you see, that's why my education was lacking this nugget - among
others).

OK. I can be certain that a user will never put in a number using more
than two decimal places - if they do I can reject it. Would I be better
off multiplying the input data by 100 and working in integars only? Then
dividing by 100 only when I need the "real" number? It sure looks like
it would make life easier.

On the other hand, the sprintf trick works. Maybe I should just try and
remember not to compare floats - that's obviously the best solution
because it'll save me asking again in the future.

Maybe, when I write my end of term report for myself, I should mention
this, maybe I'll remember it when I read what my teacher says about me.


> See 'perldoc -q 9999' for further details. Although those seem to be
> unrelated questions/issues in fact they have the same underlying reason
> which applies to virtually all programming languages.
>
>>The print statement says both weights are 42.6

>
> Try printing them with 20 digits:
> printf("%.20f", $totalIndividualWeights)
> You may be surprised.


Not *that* surprised. (at least, not after reading this thread!).


Justin.

--
Justin C, by the sea.
 
Reply With Quote
 
ccc31807
Guest
Posts: n/a
 
      06-30-2009
On Jun 30, 10:17*am, Justin C <(E-Mail Removed)> wrote:
> OK. I can be certain that a user will never put in a number using more
> than two decimal places - if they do I can reject it. Would I be better
> off multiplying the input data by 100 and working in integars only?


Test that the absolute value of the difference between the two is less
than, say, 0.001, or whatever your tolerance is. You can create a user
defined function that returns true or false for your convenience, like

if (within_tolerance( val1, val2)) #if true
{ then_do_something(); }
else #if false
{ do_something_else(); }

CC
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      06-30-2009
Justin C <(E-Mail Removed)> wrote:
>On 2009-06-29, Jürgen Exner <(E-Mail Removed)> wrote:
>> You forgot the first commandment of computer numerics:
>>
>> Thou shalt not use equality for floating point numbers!

>
>OK. I can be certain that a user will never put in a number using more
>than two decimal places - if they do I can reject it. Would I be better
>off multiplying the input data by 100 and working in integars only?


That would be one common approach to avoid any inaccuracies caused by
floating point arithmetic.

>Then
>dividing by 100 only when I need the "real" number? It sure looks like
>it would make life easier.


Think of it as doing all calculations in cent instead of in dollar or
euro and only convert them into a 'human-friendly" format when printing
or reading those amounts.
If this works for your application then it's the best posible solution.

However, computer numerics are tricky, there is a reason why it is a
subject matter at university, and even that method is not fool-proof.

Example: when calculating interest on a long list of accounts, even if
you manage them internally in cent, you may get a different result when
adding up all the interest paid to each account compared to calculating
the sum of all accounts and then the interest on the lump sum. Those
rounding errors are what's driving accountants and bankers nuts because
it takes forever to find out where and why those 3 cents went missing in
action while the missing million will be spotted immediately.

>On the other hand, the sprintf trick works. Maybe I should just try and
>remember not to compare floats -


It is ok to compare floats for smaller/larger. But instead of checking
for equal you must check if the difference between the two numbers is
smaller than some tiny number. How large that tiny number is depends on
your application area, but it will never be 100% accurate.

jue
 
Reply With Quote
 
Justin C
Guest
Posts: n/a
 
      07-02-2009
On 2009-06-30, Jürgen Exner <(E-Mail Removed)> wrote:
> Justin C <(E-Mail Removed)> wrote:
>>On 2009-06-29, Jürgen Exner <(E-Mail Removed)> wrote:
>>> You forgot the first commandment of computer numerics:
>>>
>>> Thou shalt not use equality for floating point numbers!

>>
>>OK. I can be certain that a user will never put in a number using more
>>than two decimal places - if they do I can reject it. Would I be better
>>off multiplying the input data by 100 and working in integars only?

>
> That would be one common approach to avoid any inaccuracies caused by
> floating point arithmetic.


I'll try and remember this for another time I might need it.


>>On the other hand, the sprintf trick works. Maybe I should just try and
>>remember not to compare floats -

>
> It is ok to compare floats for smaller/larger. But instead of checking
> for equal you must check if the difference between the two numbers is
> smaller than some tiny number. How large that tiny number is depends on
> your application area, but it will never be 100% accurate.


Thank you, Jurgen and CC. I'm doing a straight compare of two sprintf
'numbers', but I quite like the idea of testing the difference - a
tollerance as CC put it. I might re-write the code for proof of concept,
and "doing it" actually gets it into my head better than reading it.

Justin.

--
Justin C, by the sea.
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      07-04-2009
On Thu, 02 Jul 2009 22:48:58 -0000, Justin C <(E-Mail Removed)> wrote:

>On 2009-06-30, Jürgen Exner <(E-Mail Removed)> wrote:
>> Justin C <(E-Mail Removed)> wrote:
>>>On 2009-06-29, Jürgen Exner <(E-Mail Removed)> wrote:
>>>> You forgot the first commandment of computer numerics:
>>>>
>>>> Thou shalt not use equality for floating point numbers!
>>>
>>>OK. I can be certain that a user will never put in a number using more
>>>than two decimal places - if they do I can reject it. Would I be better
>>>off multiplying the input data by 100 and working in integars only?

>>
>> That would be one common approach to avoid any inaccuracies caused by
>> floating point arithmetic.

>
>I'll try and remember this for another time I might need it.
>
>
>>>On the other hand, the sprintf trick works. Maybe I should just try and
>>>remember not to compare floats -

>>
>> It is ok to compare floats for smaller/larger. But instead of checking
>> for equal you must check if the difference between the two numbers is
>> smaller than some tiny number. How large that tiny number is depends on
>> your application area, but it will never be 100% accurate.

>
>Thank you, Jurgen and CC. I'm doing a straight compare of two sprintf
>'numbers', but I quite like the idea of testing the difference - a
>tollerance as CC put it. I might re-write the code for proof of concept,
>and "doing it" actually gets it into my head better than reading it.
>
> Justin.


The ballpark for comparisons are C functions ceil/floor (posix in perl).
Never can you compare doubles for equality, and never can you even see a
print of thier actual float value.

There is only one need for true comparisons, the is the case of
Numerical Methods absolute "difference" being less/greater than some
value. Or in the case of rounding is needed (ala the Pentium 60 bug
where zero is less than some absolute value of some really small fraction
of 1).

-sln
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
One of two identical asp.net websites not responding mills.toby@gmail.com ASP .Net 7 10-06-2008 06:51 PM
Two identical Strings stored in two different object Neroku Java 12 02-12-2007 03:32 PM
How to compare two arrays for identical objects? Harald Kirsch Java 4 04-15-2006 04:21 AM
Combine/join/merge two identical (schema) datatables wapsiii ASP .Net 0 04-10-2006 03:30 PM
Scope - do I need two identical classes, each with different scope? ann Java 13 09-13-2005 03:07 AM



Advertisments